Best practice for returning a response?

right now in my controllers I am doing a lot of echo json_encode($data); type stuff. Is this acceptable? Should I write a middleware such that I can do return $data like in laravel and the middleware will catch it and turn it into a response? What is the best practice here? Thanks…

Instead of echo, it’s better to use the PSR-7 response object.

https://www.slimframework.com/docs/v3/objects/response.html

To return a JSON response, Slim 3 provides the withJson method.
But be careful, the withJson method is not part of the PSR-7 specification.

https://www.slimframework.com/docs/v3/objects/response.html#returning-json

Thanks, odan. Is there a best practice for where to put that code? In the controller vs in a middleware? (e.g., return $data in the controller, and then the middleware sets up the status code and the json and the PSR-7 response)

Middleware

You can run code before and after your Slim application to manipulate the Request and Response objects as you see fit. This is called middleware . Why would you want to do this? Perhaps you want to protect your app from cross-site request forgery. Maybe you want to authenticate requests before your app runs. Middleware is perfect for these scenarios.

Please read the Slim documentation for more informations: Middleware - Slim Framework

Controller (Action)

The user interfaces with the view, which passes information to a controller. The controller then passes that information to a model (layer), and the model passes information back to the controller. The controller effectively stands between the view and the model. (Brandon James Savage)

A very common way to implement a controller action is a Route callback. Technically it’s just a Closure instance. Router - Slim Framework

But in real live I would suggest using Action classes (aka Single Action Controllers). This means you have a Action handler class for each route to handle the request and return a response object.

Here is an example of a very simple single action controller:

File: src/Action/HomePingAction.php

namespace App\Action;

use Psr\Http\Message\ResponseInterface;
use Slim\Http\Request;
use Slim\Http\Response;

class HomePingAction
{
    public function __invoke(Request $request, Response $response): ResponseInterface
    {
        return $response->withJson(['success' => true]);
    }
}

To register a new action handler add a routing definition in routes.php like this:

$app->any('/ping', \App\Action\HomePingAction::class);

More infos: Creating your first Slim 3 Framework Application Part 2 | Daniel Opitz - Blog