Slide 1

Slide 1 text

High Quality APIs with API Platform @nelsonkopliku

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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)

Slide 5

Slide 5 text

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/

Slide 6

Slide 6 text

Getting Started

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

Install the easy way Download the latest release

Slide 9

Slide 9 text

Extract the platform

Slide 10

Slide 10 text

docker-compose up -d

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

It’s too much! Let’s go Micro and Flex

Slide 13

Slide 13 text

Create a brand new symfony project

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

Require the official recipe TIP: composer unpack api if you want to have a look on what has been installed

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

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.

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

Remember this?

Slide 22

Slide 22 text

Resources

Slide 23

Slide 23 text

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.

Slide 24

Slide 24 text

A simple Catalog Resource - basically a model (POPO) - DTO - Used in APIs as GET /catalogs - NOT a Doctrine Entity (not necessarily)

Slide 25

Slide 25 text

@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.

Slide 26

Slide 26 text

OpenAPI spec + Swagger tools

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

Operations

Slide 29

Slide 29 text

Operations on Resources Routes/Actions GET /catalogs POST /catalogs GET /catalogs/{id} DELETE /catalogs/{id} POST /catalogs/{id}/create-pdf

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

Route is available but returns empty collection IN ACTION

Slide 32

Slide 32 text

WHERE IS THE DATA?!

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

DataProviders

Slide 36

Slide 36 text

● ApiPlatform\Core\DataProvider\CollectionDataProviderInterface (getCollection) ● ApiPlatform\Core\DataProvider\ItemDataProviderInterface (getItem) ● ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface (supports) 3 composable interfaces

Slide 37

Slide 37 text

CatalogDataProvider

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

ApiPlatform\Core\DataProvider\CollectionDataProviderInterface CatalogDataProvider::getCollection Perform logic needed to retrieve your data collection using your domain and infrastructure

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

Register in Container And the framework will use it

Slide 42

Slide 42 text

CatalogRepository (a fake one)

Slide 43

Slide 43 text

Finally some JSON

Slide 44

Slide 44 text

Item Operation

Slide 45

Slide 45 text

DataPersisters

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

CatalogDataPersister

Slide 48

Slide 48 text

Register in Container And the framework will use it

Slide 49

Slide 49 text

Create a Catalog

Slide 50

Slide 50 text

Update a Catalog

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

A bit of config

Slide 53

Slide 53 text

Annotation definition - Easy at beginning - Quite clear - Could become a mess

Slide 54

Slide 54 text

YAML definition - Clear - Easy to write - Separation

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

Serialization

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

SerializationContext Normalization Context Applied in reading operations Denormalization Context Applied in writing operations

Slide 60

Slide 60 text

SerializationContext Denormalization Context Normalization Context

Slide 61

Slide 61 text

Serialization groups Tell the serializer when to serialize/deserialize properties

Slide 62

Slide 62 text

Smart Maybe in this operation not all the properties of the resource are needed in response

Slide 63

Slide 63 text

Specific An item detail may be more detailed instead

Slide 64

Slide 64 text

Related Resources It is all about serialization groups

Slide 65

Slide 65 text

Declare properties in Resources It is all about serialization groups src/Model/Catalog.php

Slide 66

Slide 66 text

Group: catalog:detail Applied on: Catalog and Category as embedded relation Group: category:detail Applied on: Category and Catalog as embedded relation

Slide 67

Slide 67 text

Resources often need to be exposed in different formats: JSON-LD+Hydra, JSONAPI, XML

Slide 68

Slide 68 text

No content

Slide 69

Slide 69 text

ADR Action-Domain-Responder a web-specific refinement of MVC https://github.com/pmjones/adr

Slide 70

Slide 70 text

ACTION DOMAIN RESPONDER

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

Custom Operations/Actions

Slide 73

Slide 73 text

No content

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

A simple message Class

Slide 76

Slide 76 text

Execute the action It is a 202 Accepted Meaning it has been taken in consideration, But not knowing when the operation will be executed

Slide 77

Slide 77 text

Queue in Action The message was sent, someone is going to take care of it as stands in the architecture design

Slide 78

Slide 78 text

Event System

Slide 79

Slide 79 text

It is just a matter of symfony events

Slide 80

Slide 80 text

No content

Slide 81

Slide 81 text

ApiPlatform\Core\EventListener\EventPriorities

Slide 82

Slide 82 text

Event Subscribers

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

Custom reaction to something happening

Slide 85

Slide 85 text

WHEN: Before validating data (PRE_VALIDATE) WHAT: Check if can return an empty HTTP_ACCEPTED Response EventSubscriber App\EventSubscriber\DelegatableActionListener

Slide 86

Slide 86 text

Create your patterns All of Actions implementing DelegatableAction and returning nothing will be catched and a 202 empty response will be returned

Slide 87

Slide 87 text

Summary

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

THANK YOU https://github.com/nelsonkopliku/sfday2018 @nelsonkopliku