Here is a service that implements interface
interface Rating
{
function create(User $user, User $rateduser, Rating $rating, Order $order);
}
The controller acceepts the request object:
{"rating": [{"rateid": 1, "rate": 4}], "userid": 1}
When I try to pass whole data into service:
public function store(RateRequest $request)
{
$rating = RatingData::from(
[
'rateid' => $request->get('rating.rateid'),
'rate' => $request->get('rating.rate'),
]
);
$user = Auth()::user();
$rateduser = User::find($request->id);
$order = new Order;
$this->rating->create($user, $rateduser, $rating, $order);
}
How is better pass parametres into funciton using ideniticators $userid, $rateUserId, $orderId
or concrete models? Or left it such as now?
interface Rating
{
function create(int $userid, int $rateUserId, Rating $rating, int $order);
}
The controller looks dirty in my case.
Another problem what if tomorrow my model will be changed from eloquent to another? Then I have to change service methods
CodePudding user response:
I can suggest the following approach if you want to keep your controllers clean. (I do not claim that it is the only correct one)
Dto:
class RatingDto extends DataTransferObject
{
public int $rateId;
public int $rate;
}
class CreateRatingDto extends DataTransferObject
{
public int $userId;
public int $rateUserId;
/** @var RatingDto[] */
#[CastWith(ArrayCaster::class, itemType: RatingDto::class)]
public array $ratings;
}
Request:
class CreateRatingRequest extends FormRequest
{
public function rules(): array
{
return [
'ratedUserId' => 'required|integer|exists:users,id',
'ratings' => 'required|array',
'ratings.*.rateId' => 'required|integer',
'ratings.*.rate' => 'required|integer|min:1|max:5',
];
}
public function getDto(): CreateRatingDto
{
return new CreateRatingDto([
'userId' => Auth::user()->id,
'ratedUserId' => $this->input('ratedUserId'),
'ratings' => $this->input('ratings'),
]);
}
}
Interface:
interface RatingServiceInterfate
{
public function create(CreateRatingDto $dto): RatingModel;
}
Controller:
class RatingController extends Controller
{
private RatingServiceInterfate $ratingService;
public function __construct(RatingServiceInterfate $ratingService)
{
$this->ratingService = $ratingService;
}
public function store(CreateRatingRequest $request): JsonResource
{
$rating = $this->ratingService->create($request->getDto());
return new RatingResource($rating);
}
}
Also, this implementation does not bind your service to models. At any time you can write a new interface implementation and substitute it through ServiceProvider. (if for example in another part of the application you need to save data to another database not compatible with eloquent)