mariusp's avatar

How to respond with JSON and then exit (no return chain)?

Hello! I have a Controller which handles 3 tasks, in order, when the store() method is called. Any of those 3 tasks can prepare private data OR return a response()->json(). Being inside a Controller, this works, because returning from it ends that request with a JSON response. But if I want to move the tasks to a separate Service and then new that Service up from the Controller, I cannot return the JSON directly from the Service, because it returns me back to the Controller. So instead of getting a JSON response, I get a JSON string to the Controller.

Works:

class BasicOpsController extends Controller
{
    public function store(Request $request)
    {
        // ...
        return response()->json([
             'error' => $message
        ], Response::HTTP_BAD_REQUEST);
    }
}

Doesn't work:

class BasicOpsController extends Controller
{
    public function store(Request $request)
    {
        $handler = new OpsService($request);
        $handler->validateRequest();
        $handler->formatData();
        $handler->saveData();
        // ...
        // return success JSON response
    }

class OpsService
{
    public function validateRequest() 
    { 
        // might return many response()->json() until the execution is done 
    }
    public function formatData()
    {
        // might return many response()->json() until the execution is done 
    }
    public function saveData()
    {
         // might return many response()->json() until the execution is done 
    }
}

Basically what I want is to abort execution at any given point, from the Service class (not Controller)

Thank you!

0 likes
4 replies
d3xt3r's avatar

Not recommended that you stop the execution, because the response will not be sent to the browser unless (almost) every bit of code executes.

If HOWEVER AND A BIG HOWEVER, this is what you want,

response()->json($data)->send(); 
// and die to be safe
die();
5 likes
mariusp's avatar

So you say that I should not rely on send()? Why?

d3xt3r's avatar

I didn't say you cant rely on send(), i said should not attempt to break the flow.

2 likes
maatata's avatar

I know this thread is old but this might help someone who lands here You could use the following:

use Symfony\Component\HttpKernel\Exception\HttpException;

throw new HttpException($code, $message);

Please or to participate in this conversation.