Return payload in service layer In my project I am using the ADR architecture, a branch of MVC.
In my actions (Controllers) I handle only data that comes from the request.
When there is a business rule that defines which status code I return, I do this treatment in my service.
Imagine this scenario:
When editing a user, I check if the user's email already exists, if it exists, I return an error informed to your message. This treatment is done in the service, and in these cases I get the error in it.
I would like to hear from you about my approach to, in some cases, the service layer returning the payload.
Action:
class CreateUserAction extends Action
{
    private $userService;


    /**
     * @param UserService $userService
     */
    public function __construct(UserService $userService)
    {
        $this-&gt;userService = $userService;
    }

    public function handle(Request $request) : JsonResponse
    {
        $data = $request-&gt;getData();

        $payload = $this-&gt;userService-&gt;create($data, $user);

        return response()-&gt;json($payload-&gt;body, $payload-&gt;statusCode);
    }
}

Service:
class UserService extends BaseService
{
    private $userRepository;

    public function __construct(UserRepository $userRepository)
    {
        $this-&gt;userRepository = $userRepository;
    }

    public function create(array $data) : object
    {
        if ($this-&gt;userRepository-&gt;findByEmail($data['email'])) {
            $this-&gt;setPayloadError(
                __('messages.user.contributor_email_already_exists'),
                Response::HTTP_BAD_REQUEST
            );
            return $this-&gt;getPayload();
        }
        
        $userCreated = $this-&gt;userRepository-&gt;create($data);

        $this-&gt;setPayload($userCreated, Response::HTTP_CREATED);
        return $this-&gt;getPayload();

    }
}
```
In my actions (Controllers) I handle only data that comes from the request.

If above is the case you might be better off handling validation before calling service class. In other words, prepare data into a format that business service classes can understand. Same applies about a decision on which HTTP Code to return.
I am not sure why you have single responsibility controllers, a number of files would bloat very quickly in a larger application.
Controller:
class CreateUserAction extends Action
{ 
    public function handle(UserCreateRequest $request): JsonResponse
    {
        return (new UserService)-&gt;create($request-&gt;validated(), $user);

        // OR
        $user = (new UserService)-&gt;create($request-&gt;validated(), $user);

        return response($user, Response::HTTP_CREATED);
    }
}

I am not sure why you are using repository unless you are doing complex DB operation. Service should have all the business logic. This way service layer/business logic can be easier extracted and reused in other applications thanks to less dependencies.
use App/Models/User;

class UserService extends BaseService
{ 
    public function create(array $data): User
    { 
        return (new userRepository)-&gt;create($data); 

    }
}