treblle/api-responses

A package to help you keep your API Responses standardized.

0.0.2 2023-08-25 13:18 UTC

README

API Responses

Latest Version PHP Version tests Total Downloads

Integrations   •   Website   •   Docs   •   Blog   •   Twitter   •   Discord

A package to help you keep your API Responses standardized.

Installation

composer require treblle/api-responses

Usage

This package is easy to use, it is designed to be used within your controllers to return API responses that are simple and standardized.

Using the configuration

You can publish the configuration for this package using the following artisan command:

php artisan vendor:publish --tag=api-config

This will return the configuration file for this package. Currently, the configuration only covers headers used in responses.

return [
    'headers' => [
        'default' => [
            'Content-Type' => 'application/vnd.api+json',
        ],
        'error' => [
            'Content-Type' => 'application/problem+json',
        ],
    ],
];

The HeaderFactory that is used in the response classes will pull with HeaderFactory::default() or HeaderFactory::error() depending if you are returning an error or a response.

You can override the available headers using the configuration file. This is executed outside of any middleware you may be using - which will merge in relevant Headers as required, such as Rate Limiting and Cache headers you may have set.

Returning a single model

Some API endpoints just need to return a single model, in this situation you should use the ModelResponse which accepts a JsonResource representation of your model.

final class ShowController
{
    public function __invoke(Request $request, User $user): Responsable
    {
        return new ModelResponse(
            data: new UserResource(
                resource: $user,
            ),
        );
    }
}

Returning a collection of models

Other API endpoints want to return a collection of models, in these situations you should use the CollectionResponse which accepts an AnonymousResourceCollection which is a collection of Models transformed through API Resources.

final class IndexController
{
    public function __invoke(Request $request): Responsable
    {
        return new CollectionResponse(
            data: UserResource::collection(
                resource: User::query()->get(),
            ),
        );
    }
}

When something goes wrong

The best approach when something goes wrong in your API, the best approach is to allow this to bubble up the your Exception Handler and manage how you respond in one central place.

final class Handler extends ExceptionHandler
{
    public function register(): void
    {
        $this->renderable(fn (ModelNotFoundException $exception, Request $request) => new ErrorResponse(
            data: new ApiError(
                title: 'Not Found',
                detail: $exception->getMessage(),
                instance: $request->path(),
                code: ErrorCode::NOT_FOUND->value,
                link: 'https://docs.domain.com/errors/not-found',
            ),
            status: Status::NOT_FOUND,
        ));
    }
}

Sending a simple message response

Sometimes all you need to do is send a simple message back through your API. Perhaps you are pushing the logic to a background job.

final class StoreController
{
    public function __invoke(StoreRequest $request): Responsable
    {
        dispatch(new RegisterProvider($request->payload()));
        
        return new MessageResponse(
            data: 'We have accepted your request, and are processing this action.',
            status: Status::ACCEPTED,
        )
    }
}

Sending back a more complex message response

At times you want to pass back a message as well as some data, perhaps to signify actions that need to be taken.

final class LoginController
{
    public function __invoke(Request $request): Responsable
    {
        return new \Treblle\ApiResponses\Responses\ExpandedResponse(
            message: __('auth.login'),
            data: [
                'type' => 'login',
                'attributes' => [
                    'mfa' => __('auth.mfa_required'),
                ]
            ],
        )
    }
}

General Usage

This package currently contains the following responses:

  • ModelResponse: For responding a single model resource.
  • CollectionResponse: For responding a collection of models for a resource.
  • ErrorResponse: For responding when you have encountered an Error.
  • MessageResponse: For when you are returning a simple message.
  • ExpandedResponse: For when you want to send a message and some data in the response.

Please note, the ErrorResponse is not idea for any 400 responses as these are user errors such as wrong resource or Validation problems.

Community 💙

First and foremost: Star and watch this repository to stay up-to-date.

Also, follow our Blog, and on Twitter.

You can chat with the team and other members on Discord and follow our tutorials and other video material at YouTube.

Treblle Discord

Treblle YouTube

Treblle on Twitter

How to contribute

Here are some ways of contributing to making Treblle better:

  • Try out Treblle, and let us know ways to make Treblle better for you. Let us know here on Discord.
  • Join our Discord and connect with other members to share and learn from.
  • Send a pull request to any of our open source repositories on Github. Check the contribution guide on the repo you want to contribute to for more details about how to contribute. We're looking forward to your contribution!

Testing

To run the test suite:

composer run test

Credits

A table of avatars from the project's contributors

LICENSE

The MIT LIcense (MIT). Please see License File for more information.