From 2e9eabdcfbcc1c4acb759d9cceea29725d6b52ba Mon Sep 17 00:00:00 2001 From: Lynh Date: Wed, 24 Feb 2021 00:42:59 +0700 Subject: [PATCH] Update readme --- README.md | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 203 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 853f708..b8b6f11 100644 --- a/README.md +++ b/README.md @@ -6,18 +6,218 @@ [![Total Downloads][ico-downloads]][link-downloads] [![Software License][ico-license]](LICENSE.md) -## Install +Dealing with errors when building an API can be a pain. Instead of manually building error responses you can simply throw an exception and the Hades will handle the response for you. -Via Composer +## Installation + +You may use Composer to install this package into your Laravel project: ``` bash $ composer require jenky/hades ``` -## Usage +After installing Hades, add the trait `HandlesExceptionResponse` to your `app/Exceptions/Handler` and Hades will automatically catches the thrown exception and will convert it into its JSON representation. ``` php + ':message', // The exception message + 'type' => ':type', // The exception type, default to exception class name + 'status_code' => ':status_code', // The corresponding HTTP status code, default to 500 + 'errors' => ':errors', // The error bag, usually validation error + 'code' => ':code', // The exception code + 'debug' => ':debug', // The debug information +} +``` + +> The debug information only available when application is not in `production` environment and `debug` mode is on. + +Example: + +```bash +curl --location --request GET 'http://myapp.test/api/user' \ +--header 'Accept: application/json' +``` + +```js +{ + "message": "Unauthenticated.", + "type": "AuthenticationException", + "status_code": 401, + "code": 0, +} +``` + +> Any keys that aren't replaced with corresponding values will be removed from the final response. + +### + +If you would like to use different error format for your application, you should call the `Hades::errorFormat()` method in the `boot` method of your `App\Providers\AuthServiceProvider` class: + +```php +use Jenky\Hades\Hades; + +/** + * Bootstrap any application services. + * + * @return void + */ +public function boot() +{ + Hades::errorFormat([ + 'message' => ':message', + 'error_description' => ':error', + ]); +} +``` + +## Formatting Exception Response + +### Customizing Exception Type + +When converting the exception to it's JSON representation, Hades will use the exception class name as the `type`. However, you may customize this behavior by defining a `getType` method on your exception: + +```php +catch(function (InvalidOrderException $e) { + $this->replace('type', 'order_exception') + ->replace('code', 1001); + }); +} + +``` + +Prior to Laravel 8, `register` had not been available in the `app\Exceptions\Handler` yet. However you can implement the method yourself: + +```php +use Illuminate\Contracts\Container\Container; + +/** + * {@inheritdoc} + */ +public function __construct(Container $container) +{ + parent::__construct($container); + + $this->register(); +} +``` + +If you don't want to modify the exception handler, you may wish to register the exception callback in your service provider. Typically, you should call this method from the `boot` method of your application's `App\Providers\AppServiceProvider` class: + +```php +use App\Exceptions\InvalidOrderException; +use Illuminate\Contracts\Debug\ExceptionHandler; + +/** + * Bootstrap any application services. + * + * @return void + */ +public function boot() +{ + $this->app[ExceptionHandler::class]->catch(function (InvalidOrderException $e, $handler) { + $handler->replace('type', 'order_exception') + ->replace('code', 1001); + }); +} +``` + +## Content negotiation + +### Forcing the JSON Response + +By default, Laravel expects the request should contains header `Accept` with the MIME type `application/json` or custom MIME with `json` format such as `application/vnd.myapp.v1+json` in order to return JSON response. Otherwise your may get redirected to login page if the credentials are invalid or missing/passing invalid authorization token. + +While this is a good design practice, sometimes you may wish to attach the header to request automatically. To do this, you should call the `Hades::forceJsonOutput()` method within the `boot` method of your `App\Providers\AuthServiceProvider`. + +```php +use Jenky\Hades\Hades; + +/** + * Bootstrap any application services. + * + * @return void + */ +public function boot() +{ + Hades::forceJsonOutput(); +} +``` + +Hades will add the header `Accept: application/json` to all incoming API requests. If you want to use custom MIME type, you may use the `withMimeType` to specify the MIME type: + +```php +Hades::forceJsonOutput() + ->withMimeType('application/vnd.myapp.v1+json'); +``` + +### Identify API Requests + +In order to force the response to return JSON output, Hades needs to identify the incoming request so it doesn't add the `Accept` header on your normal HTML pages. + +By default, all your API routes defined in `routes/api.php` have `/api` URI prefix automatically applied. Hades will inspects the incoming request URI and determines if the API request URI has the `/api` prefix. + +To customize this behavior, you may pass the closure to `Hades::forceJsonOutput()` to instruct Hades how to identify the incoming request: + +```php +use Illuminate\Http\Request; +Hades::forceJsonOutput(function (Request $request) { + return $request->is('api/v1/*'); +}); ``` ## Change log