mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
documentation for api
This commit is contained in:
parent
2f9c7c38b5
commit
f3802e36b3
@ -13,6 +13,9 @@ API
|
|||||||
|
|
||||||
Chill provides a basic framework to build REST api.
|
Chill provides a basic framework to build REST api.
|
||||||
|
|
||||||
|
Basic configuration
|
||||||
|
*******************
|
||||||
|
|
||||||
Configure a route
|
Configure a route
|
||||||
=================
|
=================
|
||||||
|
|
||||||
@ -34,7 +37,7 @@ You can also:
|
|||||||
* `How to create your custom normalizer <https://symfony.com/doc/current/serializer/custom_normalizer.html>`_
|
* `How to create your custom normalizer <https://symfony.com/doc/current/serializer/custom_normalizer.html>`_
|
||||||
|
|
||||||
Auto-loading the routes
|
Auto-loading the routes
|
||||||
***********************
|
=======================
|
||||||
|
|
||||||
Ensure that those lines are present in your file `app/config/routing.yml`:
|
Ensure that those lines are present in your file `app/config/routing.yml`:
|
||||||
|
|
||||||
@ -47,14 +50,9 @@ Ensure that those lines are present in your file `app/config/routing.yml`:
|
|||||||
|
|
||||||
|
|
||||||
Create your model
|
Create your model
|
||||||
*****************
|
=================
|
||||||
|
|
||||||
Create your model on the usual way.
|
Create your model on the usual way:
|
||||||
|
|
||||||
If you do not use a `custom normalizer <https://symfony.com/doc/current/serializer/custom_normalizer.html>`_, you must add `annotations to create serialization groups <https://symfony.com/doc/current/components/serializer.html#attributes-groups>`_. Those groups are, by defaults:
|
|
||||||
|
|
||||||
* :code:`read` for GET requests;
|
|
||||||
* :code:`write` for POST, PUT and PATCH requests
|
|
||||||
|
|
||||||
.. code-block:: php
|
.. code-block:: php
|
||||||
|
|
||||||
@ -62,7 +60,6 @@ If you do not use a `custom normalizer <https://symfony.com/doc/current/serializ
|
|||||||
|
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\OriginRepository;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\OriginRepository;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Serializer\Annotation\Groups;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Entity(repositoryClass=OriginRepository::class)
|
* @ORM\Entity(repositoryClass=OriginRepository::class)
|
||||||
@ -74,19 +71,16 @@ If you do not use a `custom normalizer <https://symfony.com/doc/current/serializ
|
|||||||
* @ORM\Id
|
* @ORM\Id
|
||||||
* @ORM\GeneratedValue
|
* @ORM\GeneratedValue
|
||||||
* @ORM\Column(type="integer")
|
* @ORM\Column(type="integer")
|
||||||
* @Groups({"read"})
|
|
||||||
*/
|
*/
|
||||||
private $id;
|
private $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="json")
|
* @ORM\Column(type="json")
|
||||||
* @Groups({"read", "write"})
|
|
||||||
*/
|
*/
|
||||||
private $label;
|
private $label;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="date_immutable", nullable=true)
|
* @ORM\Column(type="date_immutable", nullable=true)
|
||||||
* @Groups({"read", "write"})
|
|
||||||
*/
|
*/
|
||||||
private $noActiveAfter;
|
private $noActiveAfter;
|
||||||
|
|
||||||
@ -96,7 +90,7 @@ If you do not use a `custom normalizer <https://symfony.com/doc/current/serializ
|
|||||||
|
|
||||||
|
|
||||||
Configure api
|
Configure api
|
||||||
*************
|
=============
|
||||||
|
|
||||||
Configure the api using Yaml (see the full configuration: :ref:`api_full_configuration`):
|
Configure the api using Yaml (see the full configuration: :ref:`api_full_configuration`):
|
||||||
|
|
||||||
@ -180,7 +174,7 @@ Configure the api using Yaml (see the full configuration: :ref:`api_full_configu
|
|||||||
}
|
}
|
||||||
|
|
||||||
The :code:`_index` and :code:`_entity` action
|
The :code:`_index` and :code:`_entity` action
|
||||||
=============================================
|
*********************************************
|
||||||
|
|
||||||
The :code:`_index` and :code:`_entity` action are default actions:
|
The :code:`_index` and :code:`_entity` action are default actions:
|
||||||
|
|
||||||
@ -198,7 +192,7 @@ Entity:
|
|||||||
Path: :code:`/api/1.0/person/accompanying-period/origin/{id}.{_format}`
|
Path: :code:`/api/1.0/person/accompanying-period/origin/{id}.{_format}`
|
||||||
|
|
||||||
Role
|
Role
|
||||||
====
|
****
|
||||||
|
|
||||||
By default, the key `base_role` is used to check ACL. Take care of creating the :code:`Voter` required to take that into account.
|
By default, the key `base_role` is used to check ACL. Take care of creating the :code:`Voter` required to take that into account.
|
||||||
|
|
||||||
@ -224,50 +218,8 @@ You can also define a role for each method. In this case, this role is used for
|
|||||||
GET: MY_ROLE_SEE
|
GET: MY_ROLE_SEE
|
||||||
HEAD: MY ROLE_SEE
|
HEAD: MY ROLE_SEE
|
||||||
|
|
||||||
Edit an entity: PUT and PATCH requests
|
|
||||||
=======================================
|
|
||||||
|
|
||||||
By default, PUT and PATCH requests are not enabled. You may enable it into the configuration:
|
|
||||||
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
# config/packages/chill_main.yaml
|
|
||||||
chill_main:
|
|
||||||
apis:
|
|
||||||
accompanying_period_origin:
|
|
||||||
base_path: '/api/1.0/person/bla/bla'
|
|
||||||
class: 'Chill\PersonBundle\Entity\Blah'
|
|
||||||
name: bla
|
|
||||||
actions:
|
|
||||||
_entity:
|
|
||||||
methods:
|
|
||||||
GET: true
|
|
||||||
HEAD: true
|
|
||||||
PUT: true
|
|
||||||
PATCH: true
|
|
||||||
roles:
|
|
||||||
GET: MY_ROLE_SEE
|
|
||||||
HEAD: MY ROLE_SEE
|
|
||||||
HEAD: MY ROLE_UPDATE
|
|
||||||
HEAD: MY ROLE_UPDATE
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
PUT and PATCH requests are handled on a similar way. You may use both without difference, although updating a whole object should use a PUT request, and updating part of the object should use a PATCH request.
|
|
||||||
|
|
||||||
Those two requests allow natively to update all attributes which are present in :code:`write` group, and relation which are connected in ManyToOne relation (the entity under :code:`class` config must be associated with one entity).
|
|
||||||
|
|
||||||
The api will be able to load the associated entity with a simple given :code:`id` and :code:`type`, if
|
|
||||||
|
|
||||||
* if the class is an entity, managed by Doctrine;
|
|
||||||
* if a discriminator map is present;
|
|
||||||
* if the given data has two keys: the "discriminator map" (:code:`type`) and the id. Example: :code:`{ "type": "person", "id": 2205 }`;
|
|
||||||
* if the :code:`setter` is type-hinted.
|
|
||||||
|
|
||||||
|
|
||||||
Customize the controller
|
Customize the controller
|
||||||
========================
|
************************
|
||||||
|
|
||||||
You can customize the controller by hooking into the default actions. Take care of extending :code:`Chill\MainBundle\CRUD\Controller\ApiController`.
|
You can customize the controller by hooking into the default actions. Take care of extending :code:`Chill\MainBundle\CRUD\Controller\ApiController`.
|
||||||
|
|
||||||
@ -315,7 +267,7 @@ And set your controller in configuration:
|
|||||||
HEAD: true
|
HEAD: true
|
||||||
|
|
||||||
Create your own actions
|
Create your own actions
|
||||||
=======================
|
***********************
|
||||||
|
|
||||||
You can add your own actions:
|
You can add your own actions:
|
||||||
|
|
||||||
@ -412,8 +364,182 @@ Then, create the corresponding action into your controller:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Managing association
|
||||||
|
********************
|
||||||
|
|
||||||
|
ManyToOne association
|
||||||
|
=====================
|
||||||
|
|
||||||
|
In ManyToOne association, you can add associated entities using the :code:`PATCH` request. By default, the serializer deserialize entities only with their id and discriminator type, if any.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
curl -X 'PATCH' \
|
||||||
|
'http://localhost:8001/api/1.0/person/accompanying-course/2668.json' \
|
||||||
|
-H 'accept: */*' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
# see the data sent to the server: \
|
||||||
|
-d '{
|
||||||
|
"type": "accompanying_period",
|
||||||
|
"id": 2668,
|
||||||
|
"origin": { "id": 11 }
|
||||||
|
}'
|
||||||
|
|
||||||
|
ManyToMany associations
|
||||||
|
=======================
|
||||||
|
|
||||||
|
In OneToMany association, you can easily create route for adding and removing entities, using :code:`POST` and :code:`DELETE` requests.
|
||||||
|
|
||||||
|
Prepare your entity, creating the methods :code:`addYourEntity` and :code:`removeYourEntity`:
|
||||||
|
|
||||||
|
.. code-block:: php
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Entity;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Scope;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Component\Serializer\Annotation\Groups;
|
||||||
|
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AccompanyingPeriod Class
|
||||||
|
*
|
||||||
|
* @ORM\Entity
|
||||||
|
* @ORM\Table(name="chill_person_accompanying_period")
|
||||||
|
* @DiscriminatorMap(typeProperty="type", mapping={
|
||||||
|
* "accompanying_period"=AccompanyingPeriod::class
|
||||||
|
* })
|
||||||
|
*/
|
||||||
|
class AccompanyingPeriod
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Collection
|
||||||
|
* @ORM\ManyToMany(
|
||||||
|
* targetEntity=Scope::class,
|
||||||
|
* cascade={}
|
||||||
|
* )
|
||||||
|
* @Groups({"read"})
|
||||||
|
*/
|
||||||
|
private $scopes;
|
||||||
|
|
||||||
|
public function addScope(Scope $scope): self
|
||||||
|
{
|
||||||
|
$this->scopes[] = $scope;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeScope(Scope $scope): void
|
||||||
|
{
|
||||||
|
$this->scopes->removeElement($scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Create your route into the configuration:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
chill_main:
|
||||||
|
apis:
|
||||||
|
-
|
||||||
|
class: Chill\PersonBundle\Entity\AccompanyingPeriod
|
||||||
|
name: accompanying_course
|
||||||
|
base_path: /api/1.0/person/accompanying-course
|
||||||
|
controller: Chill\PersonBundle\Controller\AccompanyingCourseApiController
|
||||||
|
actions:
|
||||||
|
scope:
|
||||||
|
methods:
|
||||||
|
POST: true
|
||||||
|
DELETE: true
|
||||||
|
GET: false
|
||||||
|
HEAD: false
|
||||||
|
PUT: false
|
||||||
|
PATCH: false
|
||||||
|
roles:
|
||||||
|
POST: CHILL_PERSON_ACCOMPANYING_PERIOD_SEE
|
||||||
|
DELETE: CHILL_PERSON_ACCOMPANYING_PERIOD_SEE
|
||||||
|
GET: null
|
||||||
|
HEAD: null
|
||||||
|
PUT: null
|
||||||
|
PATCH: null
|
||||||
|
controller_action: null
|
||||||
|
path: null
|
||||||
|
single-collection: single
|
||||||
|
|
||||||
|
This will create a new route, which will accept two methods: DELETE and POST:
|
||||||
|
|
||||||
|
.. code-block:: raw
|
||||||
|
|
||||||
|
+--------------+---------------------------------------------------------------------------------------+
|
||||||
|
| Property | Value |
|
||||||
|
+--------------+---------------------------------------------------------------------------------------+
|
||||||
|
| Route Name | chill_api_single_accompanying_course_scope |
|
||||||
|
| Path | /api/1.0/person/accompanying-course/{id}/scope.{_format} |
|
||||||
|
| Path Regex | {^/api/1\.0/person/accompanying\-course/(?P<id>[^/]++)/scope\.(?P<_format>[^/]++)$}sD |
|
||||||
|
| Host | ANY |
|
||||||
|
| Host Regex | |
|
||||||
|
| Scheme | ANY |
|
||||||
|
| Method | POST|DELETE |
|
||||||
|
| Requirements | {id}: \d+ |
|
||||||
|
| Class | Symfony\Component\Routing\Route |
|
||||||
|
| Defaults | _controller: csapi_accompanying_course_controller:scopeApi |
|
||||||
|
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
|
||||||
|
+--------------+---------------------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Then, create the controller action. Call the method:
|
||||||
|
|
||||||
|
.. code-block:: php
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Controller;
|
||||||
|
|
||||||
|
use Chill\MainBundle\CRUD\Controller\ApiController;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Chill\MainBundle\Entity\Scope;
|
||||||
|
|
||||||
|
class MyController extends ApiController
|
||||||
|
{
|
||||||
|
public function scopeApi($id, Request $request, string $_format): Response
|
||||||
|
{
|
||||||
|
return $this->addRemoveSomething('scope', $id, $request, $_format, 'scope', Scope::class, [ 'groups' => [ 'read' ] ]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
This will allow to add a scope by his id, and delete them.
|
||||||
|
|
||||||
|
Curl requests:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# add a scope with id 5
|
||||||
|
curl -X 'POST' \
|
||||||
|
'http://localhost:8001/api/1.0/person/accompanying-course/2868/scope.json' \
|
||||||
|
-H 'accept: */*' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"type": "scope",
|
||||||
|
"id": 5
|
||||||
|
}'
|
||||||
|
|
||||||
|
# remove a scope with id 5
|
||||||
|
curl -X 'DELETE' \
|
||||||
|
'http://localhost:8001/api/1.0/person/accompanying-course/2868/scope.json' \
|
||||||
|
-H 'accept: */*' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"id": 5,
|
||||||
|
"type": "scope"
|
||||||
|
}'
|
||||||
|
|
||||||
|
|
||||||
Serialization for collection
|
Serialization for collection
|
||||||
============================
|
****************************
|
||||||
|
|
||||||
A specific model has been defined for returning collection:
|
A specific model has been defined for returning collection:
|
||||||
|
|
||||||
@ -432,8 +558,9 @@ A specific model has been defined for returning collection:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Where this is relevant, this model should be re-used in custom controller actions.
|
||||||
|
|
||||||
This can be achieved quickly by assembling results into a :code:`Chill\MainBundle\Serializer\Model\Collection`. The pagination information is given by using :code:`Paginator` (see :ref:`Pagination <pagination-ref>`).
|
In custom actions, this can be achieved quickly by assembling results into a :code:`Chill\MainBundle\Serializer\Model\Collection`. The pagination information is given by using :code:`Paginator` (see :ref:`Pagination <pagination-ref>`).
|
||||||
|
|
||||||
.. code-block:: php
|
.. code-block:: php
|
||||||
|
|
||||||
@ -454,7 +581,7 @@ This can be achieved quickly by assembling results into a :code:`Chill\MainBundl
|
|||||||
.. _api_full_configuration:
|
.. _api_full_configuration:
|
||||||
|
|
||||||
Full configuration example
|
Full configuration example
|
||||||
==========================
|
**************************
|
||||||
|
|
||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
@ -501,39 +628,4 @@ Full configuration example
|
|||||||
single-collection: single
|
single-collection: single
|
||||||
base_role: null
|
base_role: null
|
||||||
|
|
||||||
Maintaining an OpenApi
|
|
||||||
======================
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
This is experimental and may change. Keep reading this part.
|
|
||||||
|
|
||||||
Accessing swagger
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
The swagger UI is accessible through `<http://localhost:8001/_dev/swagger>`_
|
|
||||||
|
|
||||||
This is possible only in development mode.
|
|
||||||
|
|
||||||
You must be authenticated with a valid user to access it.
|
|
||||||
|
|
||||||
Maintaining specs
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
Each bundle should have an `open api 3.0 spec file <https://swagger.io/docs/specification/about/>`_ at the bundle's root, and name :code:`chill.api.specs.yaml`.
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
Update the command :code:`specs-build` into `package.json` when adding a new api file.
|
|
||||||
|
|
||||||
The specs may be compiled from the different bundles filed, and validated using docker node:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
./docker-node.sh
|
|
||||||
# build the openapi
|
|
||||||
yarn specs-build
|
|
||||||
# validate
|
|
||||||
yarn specs-validate
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user