├── .github ├── FUNDING.yml └── workflows │ ├── ci.yml │ └── static.yml ├── .php-cs-fixer.dist.php ├── src ├── Transformer │ └── AbstractTransformer.php ├── ResponseModelInterface.php ├── Model │ ├── AbstractMeta.php │ ├── ErrorWithViolation.php │ ├── Message.php │ ├── MultipleError.php │ ├── Error.php │ └── AbstractError.php └── ResponseFactory.php ├── composer.json ├── CHANGELOG.md ├── LICENSE └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [Nyholm] 4 | -------------------------------------------------------------------------------- /.php-cs-fixer.dist.php: -------------------------------------------------------------------------------- 1 | in(__DIR__.'/src') 5 | ->in(__DIR__.'/tests') 6 | ; 7 | 8 | return (new PhpCsFixer\Config()) 9 | ->setRules([ 10 | '@Symfony' => true, 11 | ]) 12 | ->setFinder($finder) 13 | ; 14 | -------------------------------------------------------------------------------- /src/Transformer/AbstractTransformer.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | interface ResponseModelInterface 11 | { 12 | public function getHttpStatusCode(): int; 13 | 14 | public function getPayload(): array; 15 | } 16 | -------------------------------------------------------------------------------- /src/Model/AbstractMeta.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | abstract class AbstractMeta implements ResponseModelInterface 13 | { 14 | private $meta; 15 | private $httpStatusCode; 16 | 17 | final public function __construct(array $meta, int $httpStatusCode) 18 | { 19 | $this->httpStatusCode = $httpStatusCode; 20 | $this->meta = $meta; 21 | } 22 | 23 | public function getHttpStatusCode(): int 24 | { 25 | return $this->httpStatusCode; 26 | } 27 | 28 | public function getPayload(): array 29 | { 30 | return [ 31 | 'meta' => $this->meta, 32 | ]; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Model/ErrorWithViolation.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | class ErrorWithViolation extends AbstractError 13 | { 14 | /** 15 | * @return static 16 | */ 17 | public static function create(ConstraintViolationInterface $violation, string $title = 'Validation failed') 18 | { 19 | $model = new static($title, 400); 20 | $model->setDescription((string) $violation->getMessage()); 21 | $model->setSource([ 22 | 'parameter' => $violation->getPropertyPath(), 23 | // @deprecated The 'message' will be removed in a future version 24 | 'message' => $violation->getMessage(), 25 | ]); 26 | 27 | return $model; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Model/Message.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class Message extends AbstractMeta 11 | { 12 | /** 13 | * @return static 14 | */ 15 | final public static function create(string $message, int $httpStatusCode) 16 | { 17 | return new static(['message' => $message], $httpStatusCode); 18 | } 19 | 20 | /** 21 | * @return static 22 | */ 23 | public static function ok(string $message = 'OK') 24 | { 25 | return static::create($message, 200); 26 | } 27 | 28 | /** 29 | * @return static 30 | */ 31 | public static function created(string $message = 'Created') 32 | { 33 | return static::create($message, 201); 34 | } 35 | 36 | /** 37 | * @return static 38 | */ 39 | public static function accepted(string $message = 'Accepted') 40 | { 41 | return static::create($message, 202); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "happyr/json-api-response-factory", 3 | "description": "Response factory in compliance with apijson", 4 | "license": "MIT", 5 | "type": "library", 6 | "authors": [ 7 | { 8 | "name": "Radoje Albijanic", 9 | "email": "radoje.albijanic@gmail.com" 10 | }, 11 | { 12 | "name": "Tobias Nyholm", 13 | "email": "tobias.nyholm@gmail.com" 14 | } 15 | ], 16 | "require": { 17 | "php": ">=7.4", 18 | "ext-json": "*", 19 | "league/fractal": "^0.18 || ^0.19 || ^0.20", 20 | "symfony/http-foundation": "^5.4 || ^6.0 || ^7.0", 21 | "symfony/validator": "^5.4 || ^6.0 || ^7.0" 22 | }, 23 | "require-dev": { 24 | "nyholm/nsa": "^1.1", 25 | "phpunit/phpunit": "^9.5" 26 | }, 27 | "minimum-stability": "dev", 28 | "prefer-stable": true, 29 | "autoload": { 30 | "psr-4": { 31 | "Happyr\\JsonApiResponseFactory\\": "src/" 32 | } 33 | }, 34 | "autoload-dev": { 35 | "psr-4": { 36 | "Tests\\Happyr\\JsonApiResponseFactory\\": "tests/" 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release. 4 | 5 | ## 0.6.0 6 | 7 | ### Added 8 | 9 | - Copy `source.message` to `detail` in `ErrorWithViolation`. Next version will remove the `source.message`. 10 | 11 | ## 0.5.0 12 | 13 | ### Added 14 | 15 | - Support for fractal 0.20.0 16 | 17 | ### Removed 18 | 19 | - Support for PHP 7.2 and 7.3 20 | - Support for Symfony 4 21 | 22 | ## 0.4.0 23 | 24 | ### Fixed 25 | 26 | - Use late static binding on factories of Error 27 | 28 | ## 0.3.0 29 | 30 | ### Added 31 | 32 | - Support for Symfony 6 33 | 34 | ### Changed 35 | 36 | - Content-Type depends on the serializer used or the second parameter for `ResponseFactory`. 37 | - Removed `final` keyword from models 38 | 39 | ### Removed 40 | 41 | - Message::noContent() 42 | 43 | ## 0.2.0 44 | 45 | ### Added 46 | 47 | - Support for Symfony 5 48 | 49 | ## 0.1.2 50 | 51 | ### Added 52 | 53 | - `meta` can be passed to item/collection create 54 | ## 0.2.0 55 | 56 | ### Added 57 | 58 | - Symfony 5 support 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Happyr 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/Model/MultipleError.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | class MultipleError implements ResponseModelInterface 13 | { 14 | private $httpStatusCode; 15 | 16 | /** 17 | * @var AbstractError[] 18 | */ 19 | private $errors; 20 | 21 | public function __construct(int $httpStatusCode, array $errors) 22 | { 23 | $this->httpStatusCode = $httpStatusCode; 24 | foreach ($errors as $error) { 25 | $this->addError($error); 26 | } 27 | } 28 | 29 | public function addError(AbstractError $error): void 30 | { 31 | $this->errors[] = $error; 32 | } 33 | 34 | public function getHttpStatusCode(): int 35 | { 36 | return $this->httpStatusCode; 37 | } 38 | 39 | public function getPayload(): array 40 | { 41 | $data = []; 42 | foreach ($this->errors as $error) { 43 | $data[] = $error->getErrorData(); 44 | } 45 | 46 | return [ 47 | 'errors' => $data, 48 | ]; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Model/Error.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class Error extends AbstractError 11 | { 12 | /** 13 | * @return static 14 | */ 15 | public static function error(string $title, int $httpCode) 16 | { 17 | return new static($title, $httpCode); 18 | } 19 | 20 | /** 21 | * @return static 22 | */ 23 | public static function serverError(string $title = 'Internal server error') 24 | { 25 | return new static($title, 500); 26 | } 27 | 28 | /** 29 | * @return static 30 | */ 31 | public static function forbidden(string $title = 'Forbidden') 32 | { 33 | return new static($title, 403); 34 | } 35 | 36 | /** 37 | * @return static 38 | */ 39 | public static function notFound(string $title = 'Not Found') 40 | { 41 | return new static($title, 404); 42 | } 43 | 44 | /** 45 | * @return static 46 | */ 47 | public static function unauthorized(string $title = 'Unauthorized') 48 | { 49 | return new static($title, 401); 50 | } 51 | 52 | /** 53 | * @return static 54 | */ 55 | public static function invalid(string $title = 'Bad Request') 56 | { 57 | return new static($title, 400); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | on: [pull_request] 3 | 4 | jobs: 5 | phpunit: 6 | name: PHPUnit 7 | runs-on: ubuntu-latest 8 | strategy: 9 | max-parallel: 10 10 | matrix: 11 | php: [ '7.4', '8.0'] 12 | sf_version: [ '5.4.*' ] 13 | include: 14 | - php: '8.0' 15 | sf_version: '6.0.*' 16 | - php: '8.1' 17 | sf_version: '6.0.*' 18 | - php: '8.1' 19 | sf_version: '6.1.*' 20 | 21 | steps: 22 | - name: Set up PHP 23 | uses: shivammathur/setup-php@2.7.0 24 | with: 25 | php-version: ${{ matrix.php }} 26 | coverage: none 27 | tools: flex 28 | 29 | - name: Checkout code 30 | uses: actions/checkout@v2 31 | 32 | - name: Download dependencies 33 | env: 34 | SYMFONY_REQUIRE: ${{ matrix.sf_version }} 35 | run: | 36 | composer update --no-interaction --prefer-dist --optimize-autoloader --prefer-stable 37 | 38 | - name: Run tests 39 | run: ./vendor/bin/phpunit 40 | 41 | lowest: 42 | name: Lowest deps 43 | runs-on: ubuntu-latest 44 | steps: 45 | - name: Set up PHP 46 | uses: shivammathur/setup-php@2.5.0 47 | with: 48 | php-version: 7.4 49 | coverage: none 50 | 51 | - name: Checkout code 52 | uses: actions/checkout@v2 53 | 54 | - name: Download dependencies 55 | run: | 56 | composer update --no-interaction --prefer-dist --optimize-autoloader --prefer-stable --prefer-lowest 57 | 58 | - name: Run tests 59 | env: 60 | SYMFONY_DEPRECATIONS_HELPER: "max[self]=0" 61 | run: ./vendor/bin/phpunit 62 | -------------------------------------------------------------------------------- /.github/workflows/static.yml: -------------------------------------------------------------------------------- 1 | on: [pull_request] 2 | name: Static analysis 3 | 4 | 5 | jobs: 6 | phpstan: 7 | name: PHPStan 8 | runs-on: ubuntu-22.04 9 | 10 | steps: 11 | - name: Checkout code 12 | uses: actions/checkout@v3 13 | 14 | - name: Setup PHP 15 | uses: shivammathur/setup-php@v2 16 | with: 17 | php-version: 8.1 18 | coverage: none 19 | tools: phpstan:1.10, cs2pr 20 | 21 | - name: Download dependencies 22 | uses: ramsey/composer-install@v2 23 | 24 | - name: PHPStan 25 | run: phpstan analyze --no-progress --error-format=checkstyle | cs2pr 26 | 27 | psalm: 28 | name: Psalm 29 | runs-on: ubuntu-22.04 30 | steps: 31 | - name: Checkout code 32 | uses: actions/checkout@v3 33 | 34 | - name: Setup PHP 35 | uses: shivammathur/setup-php@v2 36 | with: 37 | php-version: 8.1 38 | coverage: none 39 | tools: vimeo/psalm:5.13.0 40 | 41 | - name: Download dependencies 42 | uses: ramsey/composer-install@v2 43 | 44 | - name: Psalm 45 | run: psalm --no-progress --output-format=github 46 | 47 | php-cs-fixer: 48 | name: PHP-CS-Fixer 49 | runs-on: ubuntu-22.04 50 | 51 | steps: 52 | - name: Checkout code 53 | uses: actions/checkout@v3 54 | 55 | - name: Setup PHP 56 | uses: shivammathur/setup-php@v2 57 | with: 58 | php-version: 8.1 59 | coverage: none 60 | tools: php-cs-fixer:3.21, cs2pr 61 | 62 | - name: Display PHP-CS-Fixer version 63 | run: php-cs-fixer --version 64 | 65 | - name: PHP-CS-Fixer 66 | run: php-cs-fixer fix --dry-run --format=checkstyle | cs2pr 67 | 68 | 69 | composer-normalize: 70 | name: Composer Normalize 71 | runs-on: ubuntu-20.04 72 | 73 | steps: 74 | - name: Setup PHP 75 | uses: shivammathur/setup-php@v2 76 | with: 77 | php-version: 8.2 78 | coverage: none 79 | tools: composer-normalize 80 | 81 | - name: Checkout code 82 | uses: actions/checkout@v2 83 | 84 | - name: Normalize 85 | run: composer-normalize --dry-run 86 | -------------------------------------------------------------------------------- /src/ResponseFactory.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | final class ResponseFactory 20 | { 21 | private $fractal; 22 | private $paginator; 23 | private $cursor; 24 | private $contentType; 25 | 26 | public function __construct(Manager $fractal, string $contentType = null) 27 | { 28 | $this->fractal = $fractal; 29 | if (null === $contentType) { 30 | $contentType = $fractal->getSerializer() instanceof JsonApiSerializer ? 'application/vnd.api+json' : 'application/json'; 31 | } 32 | $this->contentType = $contentType; 33 | } 34 | 35 | public function getFractal(): Manager 36 | { 37 | return $this->fractal; 38 | } 39 | 40 | public function createWithItem($item, AbstractTransformer $transformer, array $meta = []): JsonResponse 41 | { 42 | $resource = new Item($item, $transformer, $transformer->getResourceName()); 43 | $resource->setMeta($meta); 44 | $rootScope = $this->fractal->createData($resource); 45 | 46 | return $this->createWithArray($rootScope->toArray()); 47 | } 48 | 49 | public function createWithCollection($collection, AbstractTransformer $transformer, array $meta = []): JsonResponse 50 | { 51 | $resource = new Collection($collection, $transformer, $transformer->getResourceName()); 52 | $resource->setMeta($meta); 53 | if (null !== $this->paginator) { 54 | $resource->setPaginator($this->paginator); 55 | } elseif (null !== $this->cursor) { 56 | $resource->setCursor($this->cursor); 57 | } 58 | $rootScope = $this->fractal->createData($resource); 59 | 60 | return $this->createWithArray($rootScope->toArray()); 61 | } 62 | 63 | public function withPaginator(PaginatorInterface $paginator): self 64 | { 65 | $new = clone $this; 66 | $new->paginator = $paginator; 67 | 68 | return $new; 69 | } 70 | 71 | public function withCursor(CursorInterface $cursor): self 72 | { 73 | $new = clone $this; 74 | $new->cursor = $cursor; 75 | 76 | return $new; 77 | } 78 | 79 | public function createWithResponseModel(ResponseModelInterface $model): JsonResponse 80 | { 81 | return $this->createWithArray($model->getPayload(), $model->getHttpStatusCode()); 82 | } 83 | 84 | private function createWithArray(array $array, int $statusCode = 200): JsonResponse 85 | { 86 | return new JsonResponse($array, $statusCode, [ 87 | 'Content-Type' => $this->contentType, 88 | ]); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/Model/AbstractError.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | abstract class AbstractError implements ResponseModelInterface 15 | { 16 | protected $id; 17 | protected $link; 18 | protected $httpStatusCode; 19 | protected $code; 20 | protected $title; 21 | protected $description; 22 | protected $source; 23 | protected $meta; 24 | 25 | /** 26 | * @param string $title a short, human-readable summary of the problem that SHOULD NOT change from occurrence 27 | * to occurrence of the problem, except for purposes of localization 28 | * @param int $httpStatusCode the HTTP status code applicable to this problem, expressed as a string value 29 | */ 30 | final public function __construct(string $title, int $httpStatusCode) 31 | { 32 | $this->title = $title; 33 | $this->httpStatusCode = $httpStatusCode; 34 | } 35 | 36 | public function getHttpStatusCode(): int 37 | { 38 | return $this->httpStatusCode; 39 | } 40 | 41 | /** 42 | * A unique identifier for this particular occurrence of the problem. 43 | */ 44 | public function setId(string $id): void 45 | { 46 | $this->id = $id; 47 | } 48 | 49 | /** 50 | * A link that leads to further details about this particular occurrence of the problem. 51 | */ 52 | public function setLink(string $link): void 53 | { 54 | $this->link = $link; 55 | } 56 | 57 | /** 58 | * An application-specific error code, expressed as a string value. 59 | */ 60 | public function setCode(string $code): void 61 | { 62 | $this->code = $code; 63 | } 64 | 65 | /** 66 | * A human-readable explanation specific to this occurrence of the problem. Like title, this field’s value can be localized. 67 | */ 68 | public function setDescription(string $description): void 69 | { 70 | $this->description = $description; 71 | } 72 | 73 | /** 74 | * An object containing references to the source of the error. 75 | * 76 | * May include the following keys: 77 | * - parameter: a string indicating which URI query parameter caused the error. 78 | * - pointer: a JSON Pointer [RFC6901] to the associated entity in the request document [e.g. "/data" for a primary 79 | * data object, or "/data/attributes/title" for a specific attribute]. 80 | */ 81 | public function setSource(array $source): void 82 | { 83 | $this->source = $source; 84 | } 85 | 86 | /** 87 | * a meta object containing non-standard meta-information about the error. 88 | * 89 | * @see https://jsonapi.org/format/#document-meta 90 | */ 91 | public function setMeta(array $meta): void 92 | { 93 | $this->meta = $meta; 94 | } 95 | 96 | public function getPayload(): array 97 | { 98 | return [ 99 | 'errors' => [$this->getErrorData()], 100 | ]; 101 | } 102 | 103 | /** 104 | * Get the error object. 105 | */ 106 | public function getErrorData(): array 107 | { 108 | $error = [ 109 | 'status' => (string) $this->httpStatusCode, 110 | 'title' => $this->title, 111 | ]; 112 | 113 | if (null !== $this->id) { 114 | $error['id'] = $this->id; 115 | } 116 | 117 | if (null !== $this->code) { 118 | $error['code'] = $this->code; 119 | } 120 | 121 | if (null !== $this->description) { 122 | $error['detail'] = $this->description; 123 | } 124 | 125 | if (null !== $this->source) { 126 | $error['source'] = $this->source; 127 | } 128 | 129 | if (null !== $this->meta) { 130 | $error['meta'] = $this->meta; 131 | } 132 | 133 | if (null !== $this->link) { 134 | $error['links'] = ['about' => $this->link]; 135 | } 136 | 137 | return $error; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JsonApi Response factory 2 | 3 | [![Latest Version](https://img.shields.io/github/release/happyr/json-api-response-factory.svg?style=flat-square)](https://github.com/happyr/json-api-response-factory/releases) 4 | [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE) 5 | [![Total Downloads](https://img.shields.io/packagist/dt/happyr/json-api-response-factory.svg?style=flat-square)](https://packagist.org/packages/happyr/json-api-response-factory) 6 | 7 | A small wrapper around `league/fractal` to support JsonApi error AND success responses. 8 | 9 | ## Install 10 | 11 | ``` 12 | composer require happyr/json-api-response-factory 13 | ``` 14 | ## Usage 15 | 16 | `ResponseFactory` can be used for creating single object, collection of objects or custom responses. 17 | 18 | ### Transformers 19 | 20 | Each object that is used in the response needs a transformer that implements `Happyr\JsonApiResponseFactory\Transformer\AbstractTransformer`: 21 | 22 | ```php 23 | use Happyr\JsonApiResponseFactory\Transformer\AbstractTransformer; 24 | 25 | final class FooTransformer extends AbstractTransformer 26 | { 27 | public function getResourceName(): string 28 | { 29 | return 'foo'; 30 | } 31 | 32 | public function transform(Foo $item): array 33 | { 34 | return [ 35 | 'id' => $item->getId(), 36 | 'bar' => (string)$item->getBar(), 37 | ]; 38 | } 39 | } 40 | ``` 41 | 42 | ### Response with single item 43 | 44 | ```php 45 | $item = new Foo('bar'); 46 | $response = $responseFactory->createWithItem($item, new FooTransformer()); 47 | ``` 48 | Response will look like this: 49 | ```json 50 | { 51 | "data": { 52 | "type": "foo", 53 | "id": "1", 54 | "attributes": { 55 | "bar": "bar" 56 | } 57 | } 58 | } 59 | ``` 60 | ### Response with collection of items 61 | 62 | ```php 63 | $items = [ 64 | new Foo('bar'), 65 | new Foo('baz'), 66 | ]; 67 | $response = $responseFactory->createWithCollection($items, new FooTransformer()); 68 | ``` 69 | Response will look like this: 70 | ```json 71 | { 72 | "data": [ 73 | { 74 | "type": "foo", 75 | "id": "1", 76 | "attributes": { 77 | "bar": "bar" 78 | } 79 | }, 80 | { 81 | "type": "foo", 82 | "id": "2", 83 | "attributes": { 84 | "bar": "baz" 85 | } 86 | } 87 | ] 88 | } 89 | ``` 90 | 91 | ### Custom responses 92 | 93 | To use response `ResponseFactory` to create response with custom payload/status codes you should create class that implements `Happyr\JsonApiResponseFactory\ResponseModelInterface`: 94 | 95 | ```php 96 | use Happyr\JsonApiResponseFactory\ResponseModelInterface; 97 | 98 | final class InvalidRequestResponseModel implements ResponseModelInterface 99 | { 100 | public function getHttpStatusCode() : int 101 | { 102 | return 400; 103 | } 104 | 105 | public function getPayload() : array 106 | { 107 | return [ 108 | 'error' => 'Invalid request.', 109 | ]; 110 | } 111 | } 112 | ``` 113 | and pass it to response factory: 114 | 115 | ```php 116 | $model = new InvalidRequestResponseModel(); 117 | $response = $responseFactory->createWithResponseModel($model); 118 | ``` 119 | Response will look lie this: 120 | ```json 121 | { 122 | "error": "Invalid request." 123 | } 124 | ``` 125 | In `src/Model/` there are models for usual message responses (accepted, created etc), and error responses in compliance with json-api error standard 126 | that you can use, or take a hint how we are using the library and write your own models. 127 | 128 | Example response for message: 129 | ```json 130 | { 131 | "meta": { 132 | "message": "Accepted" 133 | } 134 | } 135 | ``` 136 | 137 | Example response for validation failed: 138 | ```json 139 | { 140 | "errors": [ 141 | { 142 | "status": "400", 143 | "title": "Validation failed", 144 | "detail": "This value should not be blank.", 145 | "source": { 146 | "parameter": "foo", 147 | }, 148 | "links": { 149 | "about": "http://docs.docs/errors/missing-parameter" 150 | } 151 | }, 152 | { 153 | "status": "400", 154 | "title": "Validation failed", 155 | "detail": "This value has to be larger than 30.", 156 | "source": { 157 | "parameter": "bar", 158 | }, 159 | "links": { 160 | "about": "http://docs.docs/errors/range" 161 | } 162 | } 163 | ] 164 | } 165 | ``` 166 | 167 | --------------------------------------------------------------------------------