Upgrade to Pro — share decks privately, control downloads, hide ads and more …

High Quality APIs with API Platform

High Quality APIs with API Platform

APIs are must nowadays. We'll see how API Platform can help us bringing functional api platforms to production quickly. We will identify the key concepts of the framework, we will understand how to instruct it according to our needs and how it naturally integrates into the Symfony ecosystem.

9d3339bce40aa3575efae8d5ebf28400?s=128

Nelson Kopliku

October 19, 2018
Tweet

Transcript

  1. High Quality APIs with API Platform @nelsonkopliku

  2. https://github.com/api-platform/api-platform

  3. Why do we talk about APIs? Essentially because our business

    is required to be: - Multichannel - Cross-device - Distributed (maybe) - Decoupled from client - Secure - Cloud native - ... So, we have to think about APIs in an API-centric world
  4. Why do we talk about API Platform? - modern open

    source framework for API-driven projects - Standards everywhere (JSON-LD, HAL, OpenAPI...) - Great DX - Best practices - Fully integrated with Symfony - Built on shoulders of Giants (Symfony, Doctrine, Docker)
  5. Who is behind API Platform? Kévin Dunglas • Symfony Core

    Team Member • Creator of API Platform https://github.com/dunglas https://twitter.com/dunglas https://dunglas.fr/
  6. Getting Started

  7. None
  8. Install the easy way Download the latest release

  9. Extract the platform

  10. docker-compose up -d

  11. None
  12. It’s too much! Let’s go Micro and Flex

  13. Create a brand new symfony project

  14. None
  15. Require the official recipe TIP: composer unpack api if you

    want to have a look on what has been installed
  16. None
  17. Can we do better than this? Do we really need

    all of those vendors? - translation - validator - CORS - ORM - security (yes, please) - … Maybe in a monolithic approach, but probably it would be preferable to keep things simple. The point is to focus on what our application really needs.
  18. Yes, we should do better Require the strictly-necessary packages composer

    req annotations symfony/asset twig api-platform/core - NO translation - NO validator - NO CORS - NO ORM - NO security - Nothing If SwaggerUI is not needed twig can be dropped too It is up to us to us to design applications: - well scoped - extensible in time - with clear dependencies
  19. THINK ON WHAT YOU REALLY NEED - Does my app

    need to talk to a database? Maybe some CRUD? composer req orm - Does my data come from some nosql or any other 3rd party source? Redis, Algolia, Elastic composer req snc/redis-bundle composer req algolia/search-bundle composer req friendsofsymfony/elastica-bundle - Does my data need to be validated? Input data should be validated. composer req validator - Do I need an http client to request some third party APIs? composer req http - Do I need security in my APIs? composer req security composer req jwt-auth - Do I need CORS? composer req cors COMPOSE UP
  20. INSTALLATION SUMMARY Choose your way: • Download and docker-compose up

    the whole platform • Create a brand new symfony projects and require api • Require the core and build from bare minimum
  21. Remember this?

  22. Resources

  23. BASICS - Routes represent the way we request for something

    or for something to happen - Our software takes care of understanding what was requested and its context - software elaborates and returns a response for the given request often by handling some meaningful models or resources.
  24. A simple Catalog Resource - basically a model (POPO) -

    DTO - Used in APIs as GET /catalogs - NOT a Doctrine Entity (not necessarily)
  25. @ApiResource Indicates to the framework this POPO is a resource

    and should be exposed somehow. Perhaps in a REST API used by an Angular App.
  26. OpenAPI spec + Swagger tools

  27. None
  28. Operations

  29. Operations on Resources Routes/Actions GET /catalogs POST /catalogs GET /catalogs/{id}

    DELETE /catalogs/{id} POST /catalogs/{id}/create-pdf
  30. Item Operations - Give me one item GET /catalog/1 -

    Update an item PATCH /catalog/2 - Delete an item DELETE /catalog/1 - Perform custom action on items POST /catalogs/2/create-pdf Collection Operations - Give me the list of GET /catalogs - Create a Catalogue (in a list) POST /catalogs - Empty a list DELETE /catalogs OPERATION TYPES Actually there’s a third operation type (Subresource operation), but it is just a collection or an item operation depending on the context
  31. Route is available but returns empty collection IN ACTION

  32. WHERE IS THE DATA?!

  33. IT IS UP TO US TO PROVIDE DATA it's up

    to the developer to feed API Platform with an hydrated instance of this API resource object by implementing the DataProviderInterface. Basically, the data provider will query the persistence system (RDBMS, document or graph DB, external API...), and must hydrate and return the POPO that has been designed as mentioned above. When updating a state (POST, PUT, PATCH, DELETE HTTP methods), it's up to the developer to properly persist the data provided by API Platform's resource object hydrated by the serializer. To do so, there is another interface to implement: DataPersisterInterface. https://api-platform.com/docs/core/design
  34. None
  35. DataProviders

  36. • ApiPlatform\Core\DataProvider\CollectionDataProviderInterface (getCollection) • ApiPlatform\Core\DataProvider\ItemDataProviderInterface (getItem) • ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface (supports) 3

    composable interfaces
  37. CatalogDataProvider

  38. ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface CatalogDataProvider::supports Perform logic needed to permit execution of current

    DataProvider
  39. ApiPlatform\Core\DataProvider\CollectionDataProviderInterface CatalogDataProvider::getCollection Perform logic needed to retrieve your data collection

    using your domain and infrastructure
  40. ApiPlatform\Core\DataProvider\ItemDataProviderInterface CatalogDataProvider::getItem Perform logic needed to retrieve your item data

    using your domain and infrastructure
  41. Register in Container And the framework will use it

  42. CatalogRepository (a fake one)

  43. Finally some JSON

  44. Item Operation

  45. DataPersisters

  46. ApiPlatform\Core\DataPersister\DataPersisterInterface (supports, persist, remove) Only one Interface

  47. CatalogDataPersister

  48. Register in Container And the framework will use it

  49. Create a Catalog

  50. Update a Catalog

  51. CONCEPT SUMMARY RESOURCES Models representing how you are returning data

    and how you want input data Not necessary the data itself, but a representation of it OPERATIONS actions we want to execute on Resources GET /catalogs PATCH /catalogs/1 DATA PROVIDER a system taking care of retrieving data from a source DATA PERSISTER a system taking care of writing data on a source
  52. A bit of config

  53. Annotation definition - Easy at beginning - Quite clear -

    Could become a mess
  54. YAML definition - Clear - Easy to write - Separation

  55. %kernel.project_dir%/config/packages/api_platform.yaml Tell the framework where your resources are

  56. https://api-platform.com/docs/core/configuration/ for full config ref Our config

  57. Serialization

  58. https://symfony.com/doc/current/components/serializer.html

  59. SerializationContext Normalization Context Applied in reading operations Denormalization Context Applied

    in writing operations
  60. SerializationContext Denormalization Context Normalization Context

  61. Serialization groups Tell the serializer when to serialize/deserialize properties

  62. Smart Maybe in this operation not all the properties of

    the resource are needed in response
  63. Specific An item detail may be more detailed instead

  64. Related Resources It is all about serialization groups

  65. Declare properties in Resources It is all about serialization groups

    src/Model/Catalog.php
  66. Group: catalog:detail Applied on: Catalog and Category as embedded relation

    Group: category:detail Applied on: Category and Catalog as embedded relation
  67. Resources often need to be exposed in different formats: JSON-LD+Hydra,

    JSONAPI, XML
  68. None
  69. ADR Action-Domain-Responder a web-specific refinement of MVC https://github.com/pmjones/adr

  70. ACTION DOMAIN RESPONDER

  71. None
  72. Custom Operations/Actions

  73. None
  74. CreatePdfAction - Action Class - Happens on a POST /catalogs/{id}

    - Could do anything - Is a service - Autowired - Just dispatches a message via a message bus - Is delegating the process to some background microservice
  75. A simple message Class

  76. Execute the action It is a 202 Accepted Meaning it

    has been taken in consideration, But not knowing when the operation will be executed
  77. Queue in Action The message was sent, someone is going

    to take care of it as stands in the architecture design
  78. Event System

  79. It is just a matter of symfony events

  80. None
  81. ApiPlatform\Core\EventListener\EventPriorities

  82. Event Subscribers

  83. EventSubscriber App\EventSubscriber\CatalogSubscriber WHEN: After reading the item on an item

    operation (POST_READ) WHAT: Check if the catalog is generated If not throw a PDFNotReadyException
  84. Custom reaction to something happening

  85. WHEN: Before validating data (PRE_VALIDATE) WHAT: Check if can return

    an empty HTTP_ACCEPTED Response EventSubscriber App\EventSubscriber\DelegatableActionListener
  86. Create your patterns All of Actions implementing DelegatableAction and returning

    nothing will be catched and a 202 empty response will be returned
  87. Summary

  88. This is API Platform Core • Concepts and tools for

    API development • Highly customizable • Founded on Symfony Components (have to know Symfony) • ADR: web-specific refinement of MVC • Multiple formats supported (JSON-LD, Hydra, JSONAPI, OpenAPI) • Create complex applications (microservices, CQRS/ES, ...) • Also a great RAD tool (in combination with Doctrine) • A pleasure to develop with
  89. THANK YOU https://github.com/nelsonkopliku/sfday2018 @nelsonkopliku