jaspr / mapper
JSON API implementation, by annotations or schemas.
Requires
- php: ^8.2
- ext-json: *
- composer/class-map-generator: ^1.0
- composer/composer: ^2.7
- fig/http-message-util: ^1.1
- jaspr/expression: ^1.1.4
- jaspr/oas-builder: ^1.1.2
- opis/json-schema: ^2.3
- psr/http-factory: ^1.0
- psr/http-server-middleware: ^1.0
- psr/log: ^1.0 || ^2.0 || ^3.0
- psr/simple-cache: ^1.0 || ^2.0 || ^3.0
- symfony/string: ^5.0 || ^6.0 || ^7.0
- symfony/translation-contracts: ^2.1
Requires (Dev)
- doctrine/collections: ^1.6.8
- phpstan/phpstan: ^1.4.6
- phpunit/phpunit: ^11.5
- rector/rector: ^1.2
- slim/psr7: ^1.3
- squizlabs/php_codesniffer: 3.7.1
- symfony/cache: ^7.1
This package is auto-updated.
Last update: 2024-12-16 11:44:09 UTC
README
Implementation 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 jaspr/mapper
Basic Usage
For simplicity, we use
$container
as some dependency provider (Dependency Injection).
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
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
MetadataRepository
To create MetadataRepository
we must use MetadataFactory
.
Usage
<?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
);
Encoder
Options
Param | Default | Description |
---|---|---|
repository | Instance of MetadataRepository. |
Usage
<?php
// First we need DocumentBuilderFactory
// Let's get MetadataRepository from DI
/** @var $container Psr\Container\ContainerInterface */
$metadataRepository = $container->get(JSONAPI\Metadata\MetadataRepository::class);
$encoder = \JSONAPI\Mapper\Encoding\EncoderFactory::createDefaultEncoder($metadataRepository)
$data = new \JSONAPI\Mapper\Test\Resources\Valid\GettersExample('id');
/** @var \JSONAPI\Mapper\Document\ResourceObjectIdentifier $identifier */
$identifier = $encoder->identify($data);
/** @var \JSONAPI\Mapper\Document\ResourceObject $resource */
$resource = $encoder->encode($data);
/** @var \JSONAPI\Mapper\Document\Document $document */
$document = $encoder->compose($data);
Request Parser
This object works with url, and parse required keywords as described at JSON API Standard
Options
Param | Default | Description |
---|---|---|
baseUrl | URL where you API lays. Must end with / to work properly with relative links. | |
repository | Instance of MetadataRepository. | |
pathParser | PathParser | Instance of PathParserInterface. Provides information about path, like resource type, resource ID, relation type, is it collection or is it relationship. |
paginationParser | OffsetStrategyParser | Instance of PaginationParserInterface. Pagination. |
sortParser | SortParser | Instance of SortParserInterface. Sort. |
inclusionParser | InclusionParser | Instance of InclusionParserInterface. Inclusion. |
fieldsetParser | FieldsetParser | Instance of FieldsetParserInterface. Sparse Fields |
filterParser | ExpressionFilterParser | FilterParserInterface instance, which is responsible for parsing filter. Filter |
bodyParser | BodyParser | Instance of BodyParserInterface. |
logger | NullLogger | LoggerInterface instance, PSR compliant logger instance. |
Filter
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
Or if you have simpler use cases you can try QuatrodotFilter:
?filter=stringProperty::contains::Bonus|boolProperty::eq::true
Pagination
I implement two of three pagination technics
- LimitOffsetPagination
- PagePagination
Includes
https://jsonapi.org/format/#fetching-includes
Sort
https://jsonapi.org/format/#fetching-sorting
Index Page
If you want use JASPR SDK to its full potential, consider expose index page.
<?php
$doc = new JSONAPI\Mapper\IndexDocument(self::$mr, self::$url);
$response = json_encode($doc);
which returns something like this:
{
"jsonapi": {
"version": "1.0"
},
"links": {
"relation": "https:\/\/unit.test.org\/relation",
"getter": "https:\/\/unit.test.org\/getter",
"meta": "https:\/\/unit.test.org\/meta",
"prop": "https:\/\/unit.test.org\/prop",
"third": "https:\/\/unit.test.org\/third"
},
"meta": {
"title": "JSON:API Index Page",
"baseUrl": "https:\/\/unit.test.org/"
}
}
And if your front-end use jaspr/client-js
library, then you can use useJsonApiWithIndex
factory to enjoy RESTful
experience.
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/jaspr')
);
$info->setLicense(
(new License('MIT'))
->setUrl('https://gitlab.com/jaspr/mapper/-/blob/5.x/LICENSE')
);
$info->setTermsOfService('https://gitlab.com/jaspr/mapper/-/blob/5.x/CONTRIBUTING.md');
$oas = $factory->create($info);
$oas->setExternalDocs(new ExternalDocumentation('https://gitlab.com/jaspr/mapper/-/wikis/home'));
$json = json_encode($oas);
For more examples, try look at tests