bednic / json-api
JSON API implementation, by annotations or schemas.
Requires
- php: ^8.1
- ext-json: *
- bednic/rich-expression-builder: ^2.0
- composer/composer: ^2.2.6
- fig/http-message-util: ^1.1
- psr/http-factory: ^1.0
- psr/http-server-middleware: ^1.0
- psr/log: ^1.1
- psr/simple-cache: ^1.0
- swaggest/json-schema: ^0.12.29
- symfony/string: ^5.1
- symfony/translation-contracts: ^2.1
Requires (Dev)
- doctrine/collections: ^1.6.8
- phpstan/phpstan: ^1.4.6
- phpunit/phpunit: ^9
- slim/psr7: ^1.3
- squizlabs/php_codesniffer: ~3.6.2
- symfony/cache: ^5.2
Suggests
- doctrine/collections: If you want use DoctrineCriteriaExpressionBuilder
- doctrine/orm: If you want use DoctrineQueryExpressionBuilder
- 10.x-dev
- 10.1.0
- 10.0.3
- 10.0.2
- 10.0.1
- 10.0.0
- 9.x-dev
- 9.0.9
- 9.0.8
- 9.0.7
- 9.0.6
- 9.0.5
- 9.0.4
- 9.0.3
- 9.0.2
- 9.0.1
- 9.0.0
- 8.x-dev
- 8.2.0
- 8.1.0
- 8.0.2
- 8.0.1
- 8.0.0
- 7.x-dev
- 7.4.4
- 7.4.3
- 7.4.2
- 7.4.1
- 7.4.0
- 7.3.0
- 7.2.0
- 7.1.2
- 7.1.1
- 7.1.0
- 7.0.0
- 6.x-dev
- 6.4.1
- 6.4.0
- 6.3.1
- 6.3.0
- 6.2.3
- 6.2.2
- 6.2.1
- 6.2.0
- 6.1.0
- 6.0.0
- 5.x-dev
- 5.2.0
- 5.1.7
- 5.1.6
- 5.1.5
- 5.1.4
- 5.1.3
- 5.1.2
- 5.1.1
- 5.1.0
- 5.0.0
- 4.x-dev
- 4.2.4
- 4.2.3
- 4.2.2
- 4.2.1
- 4.2.0
- 4.1.1
- 4.1.0
- 4.0.0
- 3.x-dev
- 3.1.1
- 3.1.0
- 3.0.1
- 3.0.0
- 2.x-dev
- 2.4.0
- 2.3.4
- 2.3.3
- 2.3.2
- 2.3.1
- 2.3.0
- 2.2.1
- 2.2.0
- 2.1.1
- 2.1.0
- 2.0.0
- 1.x-dev
- 1.0.1
- 1.0.0
This package is auto-updated.
Last update: 2022-11-18 16:57:45 UTC
README
Package is abandoned. Please use JASPR Mapper instead.
Implemtation of JSON API Standard Specification
This project goal is to create easy-to-use library to implement JSON API specification.
Whole project is at the beginning of development. So don't hesitate to help. I'm open to some good ideas how make this more customizable and friendly.
Library only provides wrappers to create valid JSON API document. Controllers and Response is on you.
Issues
You can write email or create issue in gitlab
Installation
Install library via Composer
composer require bednic/json-api
Basic Usage
For simplicity, we use
$container
as some dependency provider (Dependency Injection).
MetadataRepository
First we need create MetadataRepository
. That we get from MetadataFactory
.
<?php
/** @var $container Psr\Container\ContainerInterface */
// This is cache instance implements PSR SimpleCache
$cache = $container->get( Psr\SimpleCache\CacheInterface::class);
// This is AnnotationDriver or SchemaDriver, depends on your preferences
$driver = $container->get(\JSONAPI\Driver\Driver::class);
// Paths to your object representing resources
$paths = ['paths/to/your/resources','another/path'];
// Factory returns instance of MetadataRepository
$repository = JSONAPI\Factory\MetadataFactory::create(
$paths,
$cache,
$driver
);
DocumentBuilderFactory
Options
Param | Default | Description |
---|---|---|
metadataRepository | Instance of MetadataRepository. | |
baseURL | URL where you API lays. | |
maxIncludedItems | 625 | Maximum items included in Compound Document. This prevents to compound huge documents. |
relationshipLimit | 25 | Maximum items included in relationship collection. |
relationshipData | true | Toggle if relationships should have data attribute. |
supportInclusion | true | Toggle if server supports inclusion. |
supportSort | true | Toggle if server supports sort. |
supportPagination | true | Toggle if server supports pagination. |
paginationParser | null | PaginationParserInterface instance, which is responsible for parsing pagination. |
filterParser | null | FilterParserInterface instance, which is responsible for parsing filter. |
logger | null | LoggerInterface instance, PSR compliant logger instance. |
<?php
// First we need DocumentBuilderFactory
// Let's get MetadataRepository from DI
/** @var $container Psr\Container\ContainerInterface */
$metadataRepository = $container->get(JSONAPI\Metadata\MetadataRepository::class);
$baseURL = "http://localhost/"; // base URL where API lays
// You can initialize it by yourself
$dbf = new JSONAPI\Factory\DocumentBuilderFactory($metadataRepository, $baseURL);
// OR you can let DI make it for you
$dbf = $container->get(JSONAPI\Factory\DocumentBuilderFactory::class);
// We need PSR ServerRequestInterface instance
/** @var $request Psr\Http\Message\ServerRequestInterface */
// Here we create instance of JSONAPI\Document\Builder
$builder = $dbf->new($request);
// Your object|objects
$data = new MyObject();
// $doc here is Document instance
$doc = $builder->setData($data)->build();
Now if you encode $doc
to JSON, you're going to get full JSON API Document. More information about UriParser
is here
Describing your objects
You can choose which way you want to describe your object metadata.
With Annotations
Note: If you want to use annotations you have to use
AnnotationDriver
inMetadataFactory
Example
How you can see, setting up resource object is quiet easy. Just annotate your getter with `#[Attribute]
or
#[Relationship]
` annotation.
Schema
The important part is to implement Resource interface. Then fill up static method getSchema
.
Note: If you want to use schema you have to use
SchemaDriver
inMetadataFactory
Example
Open API Schema
This library provides lightweight wrapper around OAS. It can generate OAS v3.0.3 schema in json, so you can provide doc for your api easily.
Basic Example
$factory = new OpenAPISpecificationBuilder(
$metadataRepository,
'https://your.api.url'
);
$info = new Info('JSON:API OAS', '1.0.0');
$info->setDescription('Test specification');
$info->setContact(
(new Contact())
->setName('Tomas Benedikt')
->setEmail('tomas.benedikt@gmail.com')
->setUrl('https://gitlab.com/bednic')
);
$info->setLicense(
(new License('MIT'))
->setUrl('https://gitlab.com/bednic/json-api/-/blob/5.x/LICENSE')
);
$info->setTermsOfService('https://gitlab.com/bednic/json-api/-/blob/5.x/CONTRIBUTING.md');
$oas = $factory->create($info);
$oas->setExternalDocs(new ExternalDocumentation('https://gitlab.com/bednic/json-api/-/wikis/home'));
$json = json_encode($oas);
UriParser
This object works with url, and parse required keywords as described at JSON API Standard
Options
Param | Default | Description |
---|---|---|
request | Instance of PSR compliant ServerRequestInterface. | |
metadataRepository | Instance of MetadataRepository. | |
baseURL | URL where you API lays. | |
supportInclusion | true | Toggle if server supports inclusion. |
supportSort | true | Toggle if server supports sort. |
supportPagination | true | Toggle if server supports pagination. |
paginationParser | null | PaginationParserInterface instance, which is responsible for parsing pagination. |
filterParser | null | FilterParserInterface instance, which is responsible for parsing filter. |
logger | null | LoggerInterface instance, PSR compliant logger instance. |
PathInterface
Provides information about path, like resource type, resource ID, relation type, is it collection or is it relationship
Fieldset
https://jsonapi.org/format/#fetching-sparse-fieldsets
Filter
https://jsonapi.org/format/#fetching-filtering
As described, specification is agnostic about filter implementation. So I created, more like borrowed, expression filter from OData. So now you can use something like this:
filter=stringProperty eq 'string' and contains(stringProperty,'asdf') and intProperty in (1,2,3) or boolProperty ne true and relation.property eq null
There are for now two ExpressionBuilder
s:
DoctrineQueryExpressionBuilder
creates expression for Doctrine QueryBuilder, it comes hadny if you are using Doctrine and want more complex filteringDoctrineCriteriaExpressionBuilder
works well with ArrayCollection or PersistentCollection which is dependency of this library so it's default and you can use it too. But it provides only some basic expressions like eq, ne, etc... But you can't filter by relation property or use some functions, or expressions.ClosureExpressionBuilder
create expression tree from closures, so you do not need doctrine at all.
Pagination
https://jsonapi.org/format/#fetching-pagination
I implement two of three pagination technics
- LimitOffsetPagination
- PagePagination
- CursorPagination which is only abstract, cause it need more then just several number, so if you want use cursor based pagination, you have to implement it by yourself.
Includes
https://jsonapi.org/format/#fetching-includes