Conceptos
Serialization: la información es transformada de un objeto a un formato distinto ej: JSON
Normalization: la información es transformada de un objeto a un array. Este es un paso intermedio entre la serialización a la deserializacion. Ej: objeto -> (normalizado) Array -> Json.
En API PLATFORM, la normalization (normalizationContext) es cuando se lee información y la denormalization (denormalizationContext) cuando se escribe información
Deserilaization: la información es transformada de un formato distinto ej: JSON a un objeto
Instalacion en Symfony:
$ composer require api
$ composer require jwt-auth
$ mkdir var/jwt
$ echo "thepass" | openssl genpkey -out var/jwt/private.pem -pass stdin -aes256 -algorithm rsa -pkeyopt rsa_keygen_bits:4096
$ echo "thepass" | openssl pkey -in var/jwt/private.pem -passin stdin -out var/jwt/public.pem -pubout
$ setfacl -R -m u:www-data:rX -m u:"$(whoami)":rwX var/jwt
$ setfacl -dR -m u:www-data:rX -m u:"$(whoami)":rwX var/jwt
JWT: https://api-platform.com/docs/core/jwt/#jwt-authentication
Test
$ composer require --dev test-pack http-client justinrainbow/json-schema
// modificar phpunit.xml.dist con la versión de PHP unit que necesitamos
$ php bin/phpunit
// En env.test agregar la base de datos que vamos a usar para test
// DATABASE_URL=mysql://root:thepass@127.0.0.1:3306/database_test?serverVersion=5.7
$ php bin/console doctrine:create:database --env=dev
$ composer require --dev alice
$ composer require logger
Configuraciones de un recurso:
/**
* @ApiResource(
* collectionOperations={"get", "post"}, -> add/remove operaciones de coleccion
* itemOperations={
* "get" = {"path"= "/description_de_producto/{id}"}, -> cambia la url para ese endpoint
* "put",
* "delete"}
* )
* @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
*/
class Productos
{
/**
* @ApiResource(
* collectionOperations={"get", "post"}, -> add/remove operaciones de coleccion
* itemOperations={"get", "put", "delete"} -> add/remove operaciones de item
* shortName="Product" -> cambia el nombre de la url que por defecto toma el de la entidad
* )
* @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
*/
class Productos
{
Normalizer / DeNormalizer
/**
* @ApiResource(
* collectionOperations={"get", "post"},
* itemOperations={"get", "put", "delete"},
* normalizationContext={ -> cuando se lee información de la API
* "groups"={"products:read"}, "swagger_definition_name"="Read",
* },
* denormalizationContext={ -> cuando se escribe información de la API
* "groups"={"products:write"}, "swagger_definition_name"="Write",
* },
* )
* @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
*/
class Productos
{
/**
* @ORM\Column(type="string", length=255)
* @Groups({"products:read", "products:write"})
*/
private $title;
Serialization name
class Productos
{
/**
* @ORM\Column(type="string", length=255)
* @Groups({"products:read", "products:write"})
* @SerializedName("description")
*/
public function setTextDescription() {
Filters
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\BooleanFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\RangeFilter;
use ApiPlatform\Core\Serializer\Filter\PropertyFilter;
/**
* @ApiResource(
* collectionOperations={"get", "post"},
* itemOperations={"get", "put", "delete"},
* attributes={
* "pagination_items_per_page"=10 -> paginación
* "formats"={"jsonld", "json", "html", "jsonhal", "csv"={"text/csv"}} -> formatos que acepta la API, hay q activarlos en el config de la API
* }
* )
* @ApiFilter(BooleanFilter::class, properties={"isPublished"})
* @ApiFilter(SearchFilter::class, properties={"title": "partial"}) -> partial, exact, start, end, word_start
* @ApiFilter(RangeFilter::class, properties={"price"})
* @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
* @ApiFilter(PropertyFilter::class) -> permite devolver solo los campos que queremos: ?properties[]=title&properties[]=shortDescription
*/
class Productos
{
Seguridad en end points
/**
* @ApiResource(
* collectionOperations={
* "get",
* "post"={"security"="is_granted('ROLE_USER')"}
* "put"={
* "security"="is_granted('ROLE_USER') and object.getUser() == user",
* "security"="Only the creator can edit a cheese listing"
* },
* },
* )
* @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
*/
class Productos
{
Generar rutas en base a IRIs:
public function login(IriConverterInterface $iriConverter)
{
return new Response(null, 204, [
'Location' => $iriConverter->getIriFromItem($this->getUser())
]);
}
Deshabilitar docs en producción:
$ touch config/packages/prod/api_platform.yml
//Dentro de este archivo agregar
api_platform:
enable_docs: false
enable_entrypoint: false