# Getting Started
# System Requirements
You need PHP >= 8.0 to use pz/jsonapi-resource
.
# Installation
Library is available on Packagist (opens new window) and can be installed using Composer (opens new window).
composer require pz/jsonapi-resource
Most modern frameworks will include the Composer autoloader by default, but ensure the following file is included:
<?php
// Include the Composer autoloader
require 'vendor/autoload.php';
# Mapping
WARNING
User of the library must be at least familiar with the JSON:API specifications (opens new window).
Let's use example similar to example on JSON:API website. We will have "articles" resource with "author" relationship that is "people" resource type.
Articles.php
<?php
use JSONAPI\Resource\Attributes as JSONAPI;
#[JSONAPI\Resource('articles')]
class Articles
{
public function __construct(
protected int $id,
protected string $title,
protected People $author,
) {}
public function getId(): int
{
return $this->id;
}
#[JSONAPI\Attribute()]
public function getTitle(): string
{
return $this->title;
}
#[JSONAPI\Relationship('author')]
public function getAuthor(): ?People
{
return $this->author;
}
}
People.php
<?php
use JSONAPI\Resource\Attributes as JSONAPI;
#[JSONAPI\Resource('people')]
class People
{
public function __construct(
protected int $id,
protected string $name,
protected int $age
) {}
public function getId(): int
{
return $this->id;
}
#[JSONAPI\Attribute('name')]
public function getName(): string
{
return $this->name;
}
#[JSONAPI\Attribute('name')]
public function getAge(): int
{
return $this->age;
}
}
TIP
To use PHP attributes and make our code clear import attributes namespace and give it alias.
use JSONAPI\Resource\Attributes as JSONAPI;
# Resource Identification
PHP attribute JSONAPI\Resource\Attributes\Resource
is used for setup resource identification (opens new window).
First argument to attribute constructor required and must be string
that represent resource type
.
Next params used to set up resource id
fetcher, by default it is the getId()
method that exists in our classes.
Then we can assign Resource
attribute to our class and provide resource type next way:
#[JSONAPI\Resource('articles')]
class Articles
#[JSONAPI\Resource('people')]
class People
# Attributes
PHP attribute JSONAPI\Resource\Attributes\Attribute
is used for setting up resource attributes (opens new window).
We have 1 attribute in "articles" resource, that is "title" and it is value fetched with getTitle()
method. So we append PHP attribute to that method.
#[JSONAPI\Attribute()]
public function getTitle(): string
There are 2 attributes in our "people" resource name
and age
. Value for that attributes can be fetched accordingly by getName()
and getAge()
methods.
#[JSONAPI\Attribute('name')]
public function getName(): string
#[JSONAPI\Attribute('age')]
public function getAge(): int
# Relationships
JSONAPI\Resource\Attributes\Relationship
is used for setting up resource relationships (opens new window).
Our "articles" have 1 relationship author
, that is list of other persons. Value for the relationship can be fetched by getAuthor()
method.
#[JSONAPI\Relationship('author')]
public function getAuthor(): ?People
# Serialization
The most basic and most required usage of the mapping is serialization.
Create a new person and serialize it with JSONAPI\Resource\Serializer
.
# Simple example
This example is response to GET /people/1
JSON:API request.
<?php
// Please change the path to your autoload
include __DIR__.'/../../vendor/autoload.php';
include __DIR__.'/People.php';
use JSONAPI\Resource\Serializer;
$people = new People(1, 'Pavel Z', 31);
$serializer = new Serializer();
$data = $serializer->serialize($people);
echo json_encode(['data' => $data], JSON_PRETTY_PRINT);
Output
{
"data": {
"type": "people",
"id": "1",
"attributes": {
"name": 31
},
"links": {
"self": "/people/1"
}
}
}
# Fieldset
JSONAPI\Resource\Feildset
represents requested fieldset (opens new window). It is provided by request query string param field
.
$fields = $httpMessage->getQueryParams()['fields'];
$fieldSet = new Fieldset($fields);
# Fetching includes
JSONAPI\Resrouce\Includeset
represents requested related resources (opens new window) (relationships). It is provided by request query string param include
.
$include = $httpMessage->getQueryParams()['include'];
$includeSet = Includeset::fromString(include);
# Example with "include" and "fields"
Let's create much more complicated request example, we want to get all articles with an author
's age
.
HTTP request by JSON:API specification will look like this:
GET /articles?include=author&fields[people]=age
<?php
// Please change the path to your autoload
include __DIR__.'/../../vendor/autoload.php';
include __DIR__.'/Articles.php';
include __DIR__.'/People.php';
use JSONAPI\Resource\Fieldset;
use JSONAPI\Resource\Includeset;
use JSONAPI\Resource\Serializer;
// Prepare our mock data, in real example it is fetched using ORM
$pavel = new People(17, 'Pavel Z', 31);
$dan = new People(18, 'Dan', 43);
$article1 = new Articles(1, 'PHP JSON:API Resource', $pavel);
$article2 = new Articles(2, 'How to create JSON:API', $dan);
// Collection of all available articles
$collection = [$article1, $article2];
// fields[people]=age
$fieldset = new Fieldset(['people' => 'age']);
// include=author
$includeset = Includeset::fromString('author');
$serializer = new Serializer(
fieldset: $fieldset,
includeset: $includeset,
);
// Our main data
$data = $serializer->serialize($collection);
// It is how we fetch compound data or included data
$included = $serializer->compoundData();
echo json_encode(['data' => $data, 'included' => $included], JSON_PRETTY_PRINT);
Output
{
"data": [
{
"type": "articles",
"id": "1",
"attributes": {
"getTitle": "PHP JSON:API Resource"
},
"relationships": {
"author": {
"data": {
"type": "people",
"id": "17"
},
"links": {
"self": "/articles/1/relationships/author",
"related": "/articles/1/author"
}
}
},
"links": {
"self": "/articles/1"
}
},
{
"type": "articles",
"id": "2",
"attributes": {
"getTitle": "How to create JSON:API"
},
"relationships": {
"author": {
"data": {
"type": "people",
"id": "18"
},
"links": {
"self": "/articles/2/relationships/author",
"related": "/articles/2/author"
}
}
},
"links": {
"self": "/articles/2"
}
}
],
"included": [
{
"type": "people",
"id": "17",
"attributes": [],
"links": {
"self": "/people/17"
}
},
{
"type": "people",
"id": "18",
"attributes": [],
"links": {
"self": "/people/18"
}
}
]
}