SlideShare a Scribd company logo
1 of 90
Download to read offline
Pre-setup
• Go to: https://github.com/Locastic/webcampzg-api-platform
• Follow instructions
• If you already did this, than:
• git fetch --all
• $ git pull
• $ docker-compose exec php composer install
Building APIs in an easy
way using API Platform
Antonio Perić-Mažar

04.10.2018., #webcampzg
“API Platform is the most advanced
API platform, in any framework or
language.”
“API Platform is the most advanced
API platform, in any framework or
language.”
Fabien Potencier, SymfonyCon 2017
Antonio Perić-Mažar
CEO, Software Developer
antonio@locastic.com
@antonioperic
Locastic
• We help clients create amazing web and mobile apps (since 2011)
• mobile development
• web development
• UX/UI
• Training and Consulting
• Shift Conference, Symfony Croatia
• www.locastic.com t: @locastic
We are hiring!
• Symfony mid/senior developer
• React (javascript) mid/senior developer
• posao@locastic.com
Why API?
The web has changed
• Javascript web apps are standard (SPA)
• Users spend more time on using mobile devices than desktop or TV.
• Linked Data and the semantic web are a reality
APIs are the heart of this new web
• Central point to access data (R/W data)
• Encapsulate business logic
• Same data and same features for desktops, mobiles, TVs and etc
• It is stateless (PHP Sessions make horizontal scaling harder)
Client Apps
• HTML5 (SPA), mobile apps, TVs, Cars etc.
• Holds all the presentation logic
• Is downloaded first (SPA, shell model)
• Queries the API to retrieve and modify data using asynchronous requests
• Is 100% composed of HTML, JavaScript and assets (CSS and etc)
• Can be hosted on a CDN
Immediate benefits
• Speed (even on mobile)
• Scalability and robustness
• Development comfort
• Long term benefits
Formats, standards, patterns
HTTP + REST + JSON
• Work everywhere
• Lightweight
• Stateless
• HTTP has a powerful caching model
• Extensible (JSON-LD, Hydra, Swagger, HAL…)
• High quality tooling
HATEOAS / Linked Data
• Hypermedia as the Engine of Application State
• Hypermedia: IRI as identifier
• Ability to reference external data (like hypertext links)
• Auto discoverable <=> Generic clients
JSON-LD (JSON for Linked Data)
• Standard: W3C recommandation (since 2014)
• Machine readable data
• Easy to use: looks like a typical JSON document
• Already used by Gmail, GitHub, BBC, Microsoft, US gov…
• Compliant with technologies of the semantic web: RDF, SPARQL, triple store…
• Good for SEO
Hydra
• Describe REST APIs in JSON-LD
• = write support
• = auto-discoverable APIs
• = standard for collections, paginations, errors, filters
• Draft W3C (Work In Progress)
{
"@context": "/contexts/Book",
"@id": "/books/2",
"@type": "http://schema.org/Book",
"id": 2,
"isbn": "9790070863971",
"description": "A long but very interesting story about REST and asyncio.",
"author": "The life!",
"title": "X",
"publicationDate": "2002-01-29T00:00:00+00:00"
}
{
 "@context": "contexts/Errors",
 "@type": “hydra:Error”,
“hydra:title”: “An error occurred”,
“hydra:description”: “Not found”
}
{
"@context": "/contexts/Book",
"@id": "/books",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/books/2",
"@type": "http://schema.org/Book",
"id": 2,
"isbn": "9790070863971",
"description": "A long but very interesting story about REST and asyncio.",
"author": "The life!",
"title": "X",
"publicationDate": "2002-01-29T00:00:00+00:00"
},
…
{
"@id": "/books/31",
"@type": "http://schema.org/Book",
"id": 31,
"isbn": "9791943452827",
"description": "Tempora voluptas ut dolorem voluptates. Provident natus ipsam fugiat est ipsam quia. Sint mollitia sed facere qui
sit. Ad iusto molestias iusto autem laboriosam nulla earum eius.",
"author": "Miss Gladyce Nader I",
"title": "Voluptas doloremque esse dolor qui illo placeat harum voluptatem.",
"publicationDate": "1970-10-11T00:00:00+00:00"
}
],
"hydra:totalItems": 125,
"hydra:view": {
"@id": "/books?page=1",
"@type": "hydra:PartialCollectionView",
"hydra:first": "/books?page=1",
"hydra:last": "/books?page=5",
"hydra:next": "/books?page=2"
}
}
API Platform: the promise
• Fully featured API supporting Swagger + JSON-LD + Hydra + HAL in minutes
• An auto generated doc
• Convenient API spec and test tools using Behat
• Easy authentication management with JWT or OAuth
• CORS and HTTP cache
• All the tools you love: Doctrine ORM, Monolog, Swiftmailer...
API Platform <3 Symfony
• Built on top of Symfony full-stack
• Install any existing SF bundles
• Follow SF Best Practices
• Use your Symfony skills
• Can be used in your existing SF app
• (Optional) tightly integrated with Doctrine
Features
• CRUD
• Filters
• Serializations groups and relations
• Validation
• Pagination
• Sorting
• The event system
• Content Negation
• Extensions
• HTTP and reverse proxy caching
• Invalidation-based HTTP caching
• JS Admin apps
• GraphQL support
• And basically everything needed to build
modern APIs
— 82
— 90
— 8090——
http://locahost:90
Coding session
Book Store API
Setup
$ git fetch --all
$ git pull
$ docker-compose up -d
$ docker-compose exec php composer install
Book


id: int
isbn: string(13)
title: string (255)
abstract: text
publicationDate: date
averageReviewRate: float
author_id: int
Author


id: int
firstname: string (255)
lastname: text
birthday: date
Review


id: int
author: string (255)
review: text
rate: datetime
book_id: int
createdAt: datetime
#1 Task
CRUD for Author, Book, Review
resources
CRUD
<?php
namespace AppEntity;
class Author
{
private $id;
private $firstName;
private $lastName;
// ...
}
# api/config/packages/api_platform/
author.yaml
resources:
AppEntityAuthor:~
schema.org
{
  "@context": "http://schema.org",
  "@type": "FlightReservation",
  "reservationNumber": "RXJ34P",
  "reservationStatus": "http://schema.org/Confirmed",
  "underName": {
    "@type": "Person",
    "name": "Eva Green"
  },
  "reservationFor": {
    "@type": "Flight",
    "flightNumber": "110",
    "airline": {
      "@type": "Airline",
      "name": "United",
      "iataCode": "UA"
    },
    "departureAirport": {
      "@type": "Airport",
      "name": "San Francisco Airport",
      "iataCode": "SFO"
    },
    "departureTime": "2017-03-04T20:15:00-08:00",
    "arrivalAirport": {
      "@type": "Airport",
      "name": "John F. Kennedy International Airport",
      "iataCode": "JFK"
    },
    "arrivalTime": "2017-03-05T06:30:00-05:00"
  }
}
Using schema.org in Api Platform
resources:
AppEntityFlightReservation:
iri: 'http://schema.org/FlightReservation'
Using schema.org in Api Platform
resources:
AppEntityFlightReservation:
iri: 'http://schema.org/FlightReservation'
properties:
status:
iri: 'http://schema.org/reservationStatus'
Operations
• API Platform Core relies on the concept of operations. Operations can be
applied to a resource exposed by the API. From an implementation point of
view, an operation is a link between a resource, a route and its related
controller.
• There are two types of operations:
• Collection operations act on a collection of resources. By default two routes
are implemented: POST and GET.
• Item operations act on an individual resource. 3 default routes are
defined GET, PUT and DELETE.
Your turn!
#1 Task - create resources
Your turn!
#2 Task - add validation
Override default order
resources:
AppEntityPlayer:
attributes:
order:
lastname: ‘ASC’
Adding subresource
resources:
AppBundleEntityPlayer:
properties:
matches:
subresource:
resourceClass: ‘AppEntityMatch’
maxDepth: 1
collection: true
Your turn!
#3 Task - order by, subresource
Filters
• If Doctrine ORM support is enabled, adding filters is as easy as registering a filter
service in your api/config/services.yml file and adding an attribute to
your resource configuration.
• Filters add extra conditions to base database query
• Useful filters for the Doctrine ORM are provided with the library. You can also
create custom filters that would fit your specific needs.
Filters
• Search filter (partial, start, end, exact, ipartial, iexact)
• Date filter (?property[<after|before>]=value )
• Boolean filter (?property=[true|false|1|0])
• Numeric filter (?property=int|bigint|decimal)
• Range filter (?property[lt]|[gt]|[lte]|[gte]|[between]=value)
• Order filter (?order[property]=<asc|desc>)
• …
• Custom filters
Filters examples
# AppBundle/Resources/config/api_resources/resources.yml
resources:
AppBundleEntityPlayer:
# ...
attributes:
filters: ['player.search', 'player.order']
AppBundleEntityMatch:
# ...
attributes:
filters: ['match.date']
services:
player.search_filter:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { id: 'exact', email: 'exact', firstName: 'partial' } ]
tags: [ { name: 'api_platform.filter', id: 'player.search' } ]
match.date_filter:
parent: 'api_platform.doctrine.orm.date_filter'
arguments: [ { datetime: ~ } ]
tags: [ { name: 'api_platform.filter', id: 'match.date' } ]
player.order_filter:
parent: 'api_platform.doctrine.orm.order_filter'
arguments: [{ firstName: 'ASC', lastName: 'ACS', email: ~ }]
tags: [{ name: 'api_platform.filter', id: 'player.order' }]
Your turn!
#4 Task - filters
#5 Task
Add serialization & deserialization
groups to Player
Serialization Groups
• API Platform Core allows to choose which attributes of the resource are
exposed during the normalization (read) and denormalization (write) process. It
relies on the serialization (and deserialization) groups feature of the Symfony
Serializer component.
• allows to specify the definition of serialization using XML, YAML, or annotations.
Serialization Groups
<?php
namespace AppEntity;
use FOSUserBundleModelUser as BaseUser;
use SymfonyComponentSerializerAnnotationGroups;
class Player extends BaseUser
{
/**
* @var int
*/
protected $id;
/**
* @Groups({"player_read", "player_write"})
*/
private $firstName;
/**
* @Groups({"player_read", "player_write"})
*/
private $lastName;
/**
* @Groups({"player_read", "player_write"})
*/
protected $email;
// ...
}
# UserBundle/Resources/api_resources/resources.yml
resources:
AppEntityPlayer:
attributes:
normalization_context:
groups: ['player_read']
denormalization_context:
groups: ['player_write']
Using Different Serialization Groups
per Operation
# UserBundle/Resources/api_resources/resources.yml
resources:
AppEntityPlayer:
itemOperations:
get:
method: 'GET'
normalization_context:
groups: ['player_read', 'player_extra']
put:
method: 'PUT'
delete:
method: 'DELETE'
attributes:
normalization_context:
groups: ['player_read']
denormalization_context:
groups: ['player_write']
Your turn!
#5 Task
#6 Task
Create event subscriber for posting new
Review
Api platform events
// src/AppBundle/EventSubscriber/MatchEventSubscriber.php
class MatchEventSubscriber implements EventSubscriberInterface
{
private $matchHelper;
public function __construct(MatchHelper $matchHelper)
{
$this->matchHelper = $matchHelper;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => [['addWinner', EventPriorities::POST_VALIDATE]],
];
}
public function addWinner(GetResponseForControllerResultEvent $event)
{
$match = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if(!$match instanceof Match || $method !== 'POST') {
return;
}
$winner = $this->matchHelper->getWinner($match);
$match->setWinner($winner);
}
}
Your turn!
#6 Task
Your turn!
#7 Task - Virtual property
#8 Task
Update PWA app
Update progressive web app
• docker-compose exec client generate-api-platform-clien
• Follow instructions
JSON Web Token (JWT)
• Lightweight and simple authentication system
• Stateless: token signed and verified server-side then stored client-side and sent
with each request in an Authorization header
• Store the token in the browser local storage
API and JWT Integration
• We need to install and configure
• LexikJWTAuthenticationBundle
• JWTRefreshTokenBundle
Pagination
# app/config/config.yml
api_platform:
# ...
collection:
pagination:
items_per_page: 30 # Default value
client_items_per_page: true # Disabled by default
items_per_page_parameter_name: itemsPerPage # Default value
client_enabled: true # optional
enabled_parameter_name: pagination # optional
page_parameter_name: _page # optional
Operations
• API Platform Core relies on the concept of operations. Operations can be
applied to a resource exposed by the API. From an implementation point of
view, an operation is a link between a resource, a route and its related
controller.
• There are two types of operations:
• Collection operations act on a collection of resources. By default two routes
are implemented: POST and GET.
• Item operations act on an individual resource. 3 default routes are
defined GET, PUT and DELETE.
Custom operation
class Match
{
private $id;
/**
* @Groups({"match_read"})
*/
private $datetime;
/**
* @Groups({"match_read", "match_write"})
*/
private $playerOnePoints;
/**
* @Groups({"match_read", "match_write"})
*/
private $playerTwoPoints;
/**
* @Groups({"match_read", "match_write"})
*/
private $playerOne;
/**
* @Groups({"match_read", "match_write"})
*/
private $playerTwo;
/**
* @Groups({"match_read"})
*/
private $winner;
/**
* @Groups({"match_read"})
*/
private $result;
}
Custom operationclass Match
{
private $id;
/**
* @Groups({"match_read"})
*/
private $datetime;
/**
* @Groups({"match_read", "match_write"})
*/
private $playerOnePoints;
/**
* @Groups({"match_read", "match_write"})
*/
private $playerTwoPoints;
/**
* @Groups({"match_read", "match_write"})
*/
private $playerOne;
/**
* @Groups({"match_read", "match_write"})
*/
private $playerTwo;
/**
* @Groups({"match_read"})
*/
private $winner;
/**
* @Groups({"match_read"})
*/
private $result;
}
class MatchController extends Controller
{
/**
* @param Match $data
*
* @return Match
*/
public function getMatchAction($data)
{
$result = $data->getPlayerOne() . ' ' . $data->getPlayerOnePoints().':'
.$data->getPlayerTwoPoints() . ' ' . $data->getPlayerTwo();
$data->setResult($result);
return $data;
}
}
Custom operation
class Match
{
private $id;
/**
* @Groups({"match_read"})
*/
private $datetime;
/**
* @Groups({"match_read", "match_write"})
*/
private $playerOnePoints;
/**
* @Groups({"match_read", "match_write"})
*/
private $playerTwoPoints;
/**
* @Groups({"match_read", "match_write"})
*/
private $playerOne;
/**
* @Groups({"match_read", "match_write"})
*/
private $playerTwo;
/**
* @Groups({"match_read"})
*/
private $winner;
/**
* @Groups({"match_read"})
*/
private $result;
}
class MatchController extends Controller
{
/**
* @param Match $data
*
* @return Match
*/
public function getMatchAction($data)
{
$result = $data->getPlayerOne() . ' ' . $data->getPlayerOnePoints().':'
.$data->getPlayerTwoPoints() . ' ' . $data->getPlayerTwo();
$data->setResult($result);
return $data;
}
}
# app/config/routing.yml
get_match:
path: /api/v1/matches/{id}.{_format}
methods: ['GET']
defaults:
_controller: AppBundle:Match:getMatch
_api_resource_class: AppBundleEntityMatch
_api_item_operation_name: get
Extensions
• API Platform Core provides a system to extend queries on items and collections.
• Custom extensions must implement
the ApiPlatformCoreBridgeDoctrineOrmExtensionQuery
CollectionExtensionInterface and / or
the ApiPlatformCoreBridgeDoctrineOrmExtensionQuery
ItemExtensionInterface interfaces, to be run when querying for a
collection of items and when querying for an item respectively.
class GetPlayersExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
{
public function applyToItem(
QueryBuilder $queryBuilder,
QueryNameGeneratorInterface $queryNameGenerator,
string $resourceClass,
array $identifiers,
string $operationName = null,
array $context = []
) {
$this->addWhere($queryBuilder, $resourceClass, $operationName);
}
public function applyToCollection(
QueryBuilder $queryBuilder,
QueryNameGeneratorInterface $queryNameGenerator,
string $resourceClass,
string $operationName = null
) {
$this->addWhere($queryBuilder, $resourceClass, $operationName);
}
private function addWhere(QueryBuilder $queryBuilder, string $resourceClass, string $operationName = null)
{
if ($resourceClass != Player::class || $operationName != 'get') {
return;
}
$rootAlias = $queryBuilder->getRootAliases()[0];
$queryBuilder->andWhere(
$queryBuilder->expr()->eq($rootAlias.'.enabled', ':enabled')
)->setParameter('enabled', true);
}
}
services:
app.extension.get_players:
class: AppBundleDoctrineORMExtensionGetPlayersExtension
public: false
tags:
- { name: api_platform.doctrine.orm.query_extension.collection, priority: 9 }
- { name: api_platform.doctrine.orm.query_extension.item }
Per Resource Authorization Mechanism
namespace AppBundleEntity;
 
use ApiPlatformCoreAnnotationApiResource;
use DoctrineORMMapping as ORM;
 
/**
* @ApiResource(
*     attributes={"is_granted"="has_role('ROLE_ADMIN')"},
*     itemOperations={
*         "get"={"method"="GET", "is_granted"="object.getOwner() == user"}
*     }
* )
* @ORMEntity
*/
class Secured
{
    /**
     * @ORMColumn(type="integer")
     * @ORMId
     * @ORMGeneratedValue(strategy="AUTO")
     */
    public $id;
 
    /**
     * @ORMColumn(type="text")
     */
    public $owner;
Cache invalidation is builtin
GraphQL support
Specs and tests with Behat
Behat and its Behatch extension make testing and API easy.
# features/put.feature
Scenario: Update a resource
When I send a "PUT" request to "/people/1" with body:
"""
{
"name": "Kevin"
}
"""
Then the response status code should be 200
And the response should be in JSON
And the header "Content-Type" should be equal to "application/ld+json"
And the JSON should be equal to:
"""
{
"@context": "/contexts/Person",
"@id": "/people/1",
"@type": "Person",
"name": "Kevin",
"address": null
}
"""
More features
• ReactJS Based Admin generator
• A React/Redux Webapp Generator
• AngularJS app bootstrap
• Symfony Flex support
• Brand new docker setup (with varnish)
More features
• JSONAPI support
• MongoDB native
• GraphQL support
Thank you!
QnA?
Please rate my talk
https://joind.in/talk/d03f0

More Related Content

What's hot

Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreStormpath
 
Building Beautiful REST APIs with ASP.NET Core
Building Beautiful REST APIs with ASP.NET CoreBuilding Beautiful REST APIs with ASP.NET Core
Building Beautiful REST APIs with ASP.NET CoreStormpath
 
API Platform 2.1: when Symfony meets ReactJS (Symfony Live 2017)
API Platform 2.1: when Symfony meets ReactJS (Symfony Live 2017)API Platform 2.1: when Symfony meets ReactJS (Symfony Live 2017)
API Platform 2.1: when Symfony meets ReactJS (Symfony Live 2017)Les-Tilleuls.coop
 
Get Django, Get Hired - An opinionated guide to getting the best job, for the...
Get Django, Get Hired - An opinionated guide to getting the best job, for the...Get Django, Get Hired - An opinionated guide to getting the best job, for the...
Get Django, Get Hired - An opinionated guide to getting the best job, for the...Marcel Chastain
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreNate Barbettini
 
Creating hypermedia APIs in a few minutes using the API Platform framework
Creating hypermedia APIs in a few minutes using the API Platform frameworkCreating hypermedia APIs in a few minutes using the API Platform framework
Creating hypermedia APIs in a few minutes using the API Platform frameworkLes-Tilleuls.coop
 
06 integrate elasticsearch
06 integrate elasticsearch06 integrate elasticsearch
06 integrate elasticsearchErhwen Kuo
 
04 integrate entityframework
04 integrate entityframework04 integrate entityframework
04 integrate entityframeworkErhwen Kuo
 
(DVO308) Docker & ECS in Production: How We Migrated Our Infrastructure from ...
(DVO308) Docker & ECS in Production: How We Migrated Our Infrastructure from ...(DVO308) Docker & ECS in Production: How We Migrated Our Infrastructure from ...
(DVO308) Docker & ECS in Production: How We Migrated Our Infrastructure from ...Amazon Web Services
 
API Platform and Symfony: a Framework for API-driven Projects
API Platform and Symfony: a Framework for API-driven ProjectsAPI Platform and Symfony: a Framework for API-driven Projects
API Platform and Symfony: a Framework for API-driven ProjectsLes-Tilleuls.coop
 
Transforming WordPress Search and Query Performance with Elasticsearch
Transforming WordPress Search and Query Performance with Elasticsearch Transforming WordPress Search and Query Performance with Elasticsearch
Transforming WordPress Search and Query Performance with Elasticsearch Taylor Lovett
 
JSON REST API for WordPress
JSON REST API for WordPressJSON REST API for WordPress
JSON REST API for WordPressTaylor Lovett
 
Laravel and Django and Rails, Oh My!
Laravel and Django and Rails, Oh My!Laravel and Django and Rails, Oh My!
Laravel and Django and Rails, Oh My!Chris Roberts
 
API Platform: Full Stack Framework Resurrection
API Platform: Full Stack Framework ResurrectionAPI Platform: Full Stack Framework Resurrection
API Platform: Full Stack Framework ResurrectionLes-Tilleuls.coop
 
03 integrate webapisignalr
03 integrate webapisignalr03 integrate webapisignalr
03 integrate webapisignalrErhwen Kuo
 
Shiny, Let’s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...
Shiny, Let’s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...Shiny, Let’s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...
Shiny, Let’s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...Michael Pirnat
 
RESTful API Design Best Practices Using ASP.NET Web API
RESTful API Design Best Practices Using ASP.NET Web APIRESTful API Design Best Practices Using ASP.NET Web API
RESTful API Design Best Practices Using ASP.NET Web API💻 Spencer Schneidenbach
 
API Platform: A Framework for API-driven Projects
API Platform: A Framework for API-driven ProjectsAPI Platform: A Framework for API-driven Projects
API Platform: A Framework for API-driven ProjectsLes-Tilleuls.coop
 
CTO Night & Days 2015 Winter - AWS Mobile Development
CTO Night & Days 2015 Winter - AWS Mobile DevelopmentCTO Night & Days 2015 Winter - AWS Mobile Development
CTO Night & Days 2015 Winter - AWS Mobile Development崇之 清水
 

What's hot (20)

Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET Core
 
Building Beautiful REST APIs with ASP.NET Core
Building Beautiful REST APIs with ASP.NET CoreBuilding Beautiful REST APIs with ASP.NET Core
Building Beautiful REST APIs with ASP.NET Core
 
API Platform 2.1: when Symfony meets ReactJS (Symfony Live 2017)
API Platform 2.1: when Symfony meets ReactJS (Symfony Live 2017)API Platform 2.1: when Symfony meets ReactJS (Symfony Live 2017)
API Platform 2.1: when Symfony meets ReactJS (Symfony Live 2017)
 
Get Django, Get Hired - An opinionated guide to getting the best job, for the...
Get Django, Get Hired - An opinionated guide to getting the best job, for the...Get Django, Get Hired - An opinionated guide to getting the best job, for the...
Get Django, Get Hired - An opinionated guide to getting the best job, for the...
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET Core
 
Creating hypermedia APIs in a few minutes using the API Platform framework
Creating hypermedia APIs in a few minutes using the API Platform frameworkCreating hypermedia APIs in a few minutes using the API Platform framework
Creating hypermedia APIs in a few minutes using the API Platform framework
 
06 integrate elasticsearch
06 integrate elasticsearch06 integrate elasticsearch
06 integrate elasticsearch
 
04 integrate entityframework
04 integrate entityframework04 integrate entityframework
04 integrate entityframework
 
(DVO308) Docker & ECS in Production: How We Migrated Our Infrastructure from ...
(DVO308) Docker & ECS in Production: How We Migrated Our Infrastructure from ...(DVO308) Docker & ECS in Production: How We Migrated Our Infrastructure from ...
(DVO308) Docker & ECS in Production: How We Migrated Our Infrastructure from ...
 
API Platform and Symfony: a Framework for API-driven Projects
API Platform and Symfony: a Framework for API-driven ProjectsAPI Platform and Symfony: a Framework for API-driven Projects
API Platform and Symfony: a Framework for API-driven Projects
 
Transforming WordPress Search and Query Performance with Elasticsearch
Transforming WordPress Search and Query Performance with Elasticsearch Transforming WordPress Search and Query Performance with Elasticsearch
Transforming WordPress Search and Query Performance with Elasticsearch
 
JSON REST API for WordPress
JSON REST API for WordPressJSON REST API for WordPress
JSON REST API for WordPress
 
Laravel and Django and Rails, Oh My!
Laravel and Django and Rails, Oh My!Laravel and Django and Rails, Oh My!
Laravel and Django and Rails, Oh My!
 
API Platform: Full Stack Framework Resurrection
API Platform: Full Stack Framework ResurrectionAPI Platform: Full Stack Framework Resurrection
API Platform: Full Stack Framework Resurrection
 
03 integrate webapisignalr
03 integrate webapisignalr03 integrate webapisignalr
03 integrate webapisignalr
 
Shiny, Let’s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...
Shiny, Let’s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...Shiny, Let’s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...
Shiny, Let’s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...
 
RESTful API Design Best Practices Using ASP.NET Web API
RESTful API Design Best Practices Using ASP.NET Web APIRESTful API Design Best Practices Using ASP.NET Web API
RESTful API Design Best Practices Using ASP.NET Web API
 
RESTful Services
RESTful ServicesRESTful Services
RESTful Services
 
API Platform: A Framework for API-driven Projects
API Platform: A Framework for API-driven ProjectsAPI Platform: A Framework for API-driven Projects
API Platform: A Framework for API-driven Projects
 
CTO Night & Days 2015 Winter - AWS Mobile Development
CTO Night & Days 2015 Winter - AWS Mobile DevelopmentCTO Night & Days 2015 Winter - AWS Mobile Development
CTO Night & Days 2015 Winter - AWS Mobile Development
 

Similar to Building APIs in an easy way using API Platform

Building APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformBuilding APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformAntonio Peric-Mazar
 
Docs as Part of the Product - Open Source Summit North America 2018
Docs as Part of the Product - Open Source Summit North America 2018Docs as Part of the Product - Open Source Summit North America 2018
Docs as Part of the Product - Open Source Summit North America 2018Den Delimarsky
 
2.28.17 Introducing DSpace 7 Webinar Slides
2.28.17 Introducing DSpace 7 Webinar Slides2.28.17 Introducing DSpace 7 Webinar Slides
2.28.17 Introducing DSpace 7 Webinar SlidesDuraSpace
 
Building RESTful APIs
Building RESTful APIsBuilding RESTful APIs
Building RESTful APIsSilota Inc.
 
Beautiful REST and JSON APIs - Les Hazlewood
Beautiful REST and JSON APIs - Les HazlewoodBeautiful REST and JSON APIs - Les Hazlewood
Beautiful REST and JSON APIs - Les Hazlewoodjaxconf
 
A high profile project with Symfony and API Platform: beIN SPORTS
A high profile project with Symfony and API Platform: beIN SPORTSA high profile project with Symfony and API Platform: beIN SPORTS
A high profile project with Symfony and API Platform: beIN SPORTSSmile I.T is open
 
Harnessing Free Content with Web Service APIs
Harnessing Free Content with Web Service APIsHarnessing Free Content with Web Service APIs
Harnessing Free Content with Web Service APIsALATechSource
 
FOXX - a Javascript application framework on top of ArangoDB
FOXX - a Javascript application framework on top of ArangoDBFOXX - a Javascript application framework on top of ArangoDB
FOXX - a Javascript application framework on top of ArangoDBArangoDB Database
 
Kubernetes Architecture - beyond a black box - Part 1
Kubernetes Architecture - beyond a black box - Part 1Kubernetes Architecture - beyond a black box - Part 1
Kubernetes Architecture - beyond a black box - Part 1Hao H. Zhang
 
Rapid API Development ArangoDB Foxx
Rapid API Development ArangoDB FoxxRapid API Development ArangoDB Foxx
Rapid API Development ArangoDB FoxxMichael Hackstein
 
Drupal and Apache Stanbol
Drupal and Apache StanbolDrupal and Apache Stanbol
Drupal and Apache StanbolAlkuvoima
 
Resting on your laurels will get you powned
Resting on your laurels will get you pownedResting on your laurels will get you powned
Resting on your laurels will get you pownedDinis Cruz
 
Survival Strategies for API Documentation: Presentation to Southwestern Ontar...
Survival Strategies for API Documentation: Presentation to Southwestern Ontar...Survival Strategies for API Documentation: Presentation to Southwestern Ontar...
Survival Strategies for API Documentation: Presentation to Southwestern Ontar...Tom Johnson
 
IVS CTO Night And Day 2018 Winter - [re:Cap] Serverless & Mobile
IVS CTO Night And Day 2018 Winter - [re:Cap] Serverless & MobileIVS CTO Night And Day 2018 Winter - [re:Cap] Serverless & Mobile
IVS CTO Night And Day 2018 Winter - [re:Cap] Serverless & MobileAmazon Web Services Japan
 
Microservices and the Art of Taming the Dependency Hell Monster
Microservices and the Art of Taming the Dependency Hell MonsterMicroservices and the Art of Taming the Dependency Hell Monster
Microservices and the Art of Taming the Dependency Hell MonsterC4Media
 

Similar to Building APIs in an easy way using API Platform (20)

Building APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformBuilding APIs in an easy way using API Platform
Building APIs in an easy way using API Platform
 
REST easy with API Platform
REST easy with API PlatformREST easy with API Platform
REST easy with API Platform
 
Introduction to Monsoon PHP framework
Introduction to Monsoon PHP frameworkIntroduction to Monsoon PHP framework
Introduction to Monsoon PHP framework
 
Docs as Part of the Product - Open Source Summit North America 2018
Docs as Part of the Product - Open Source Summit North America 2018Docs as Part of the Product - Open Source Summit North America 2018
Docs as Part of the Product - Open Source Summit North America 2018
 
2.28.17 Introducing DSpace 7 Webinar Slides
2.28.17 Introducing DSpace 7 Webinar Slides2.28.17 Introducing DSpace 7 Webinar Slides
2.28.17 Introducing DSpace 7 Webinar Slides
 
Building RESTful APIs
Building RESTful APIsBuilding RESTful APIs
Building RESTful APIs
 
Beautiful REST and JSON APIs - Les Hazlewood
Beautiful REST and JSON APIs - Les HazlewoodBeautiful REST and JSON APIs - Les Hazlewood
Beautiful REST and JSON APIs - Les Hazlewood
 
A high profile project with Symfony and API Platform: beIN SPORTS
A high profile project with Symfony and API Platform: beIN SPORTSA high profile project with Symfony and API Platform: beIN SPORTS
A high profile project with Symfony and API Platform: beIN SPORTS
 
Harnessing Free Content with Web Service APIs
Harnessing Free Content with Web Service APIsHarnessing Free Content with Web Service APIs
Harnessing Free Content with Web Service APIs
 
FOXX - a Javascript application framework on top of ArangoDB
FOXX - a Javascript application framework on top of ArangoDBFOXX - a Javascript application framework on top of ArangoDB
FOXX - a Javascript application framework on top of ArangoDB
 
Kubernetes Architecture - beyond a black box - Part 1
Kubernetes Architecture - beyond a black box - Part 1Kubernetes Architecture - beyond a black box - Part 1
Kubernetes Architecture - beyond a black box - Part 1
 
Rapid API Development ArangoDB Foxx
Rapid API Development ArangoDB FoxxRapid API Development ArangoDB Foxx
Rapid API Development ArangoDB Foxx
 
Drupal and Apache Stanbol
Drupal and Apache StanbolDrupal and Apache Stanbol
Drupal and Apache Stanbol
 
Apereo OAE - Bootcamp
Apereo OAE - BootcampApereo OAE - Bootcamp
Apereo OAE - Bootcamp
 
Resting on your laurels will get you powned
Resting on your laurels will get you pownedResting on your laurels will get you powned
Resting on your laurels will get you powned
 
In app search 1
In app search 1In app search 1
In app search 1
 
Survival Strategies for API Documentation: Presentation to Southwestern Ontar...
Survival Strategies for API Documentation: Presentation to Southwestern Ontar...Survival Strategies for API Documentation: Presentation to Southwestern Ontar...
Survival Strategies for API Documentation: Presentation to Southwestern Ontar...
 
IVS CTO Night And Day 2018 Winter - [re:Cap] Serverless & Mobile
IVS CTO Night And Day 2018 Winter - [re:Cap] Serverless & MobileIVS CTO Night And Day 2018 Winter - [re:Cap] Serverless & Mobile
IVS CTO Night And Day 2018 Winter - [re:Cap] Serverless & Mobile
 
Intro to CakePHP
Intro to CakePHPIntro to CakePHP
Intro to CakePHP
 
Microservices and the Art of Taming the Dependency Hell Monster
Microservices and the Art of Taming the Dependency Hell MonsterMicroservices and the Art of Taming the Dependency Hell Monster
Microservices and the Art of Taming the Dependency Hell Monster
 

More from Antonio Peric-Mazar

You call yourself a Senior Developer?
You call yourself a Senior Developer?You call yourself a Senior Developer?
You call yourself a Senior Developer?Antonio Peric-Mazar
 
Using API Platform to build ticketing system #symfonycon
Using API Platform to build ticketing system #symfonyconUsing API Platform to build ticketing system #symfonycon
Using API Platform to build ticketing system #symfonyconAntonio Peric-Mazar
 
Using API platform to build ticketing system (translations, time zones, ...) ...
Using API platform to build ticketing system (translations, time zones, ...) ...Using API platform to build ticketing system (translations, time zones, ...) ...
Using API platform to build ticketing system (translations, time zones, ...) ...Antonio Peric-Mazar
 
Are you failing at being agile? #digitallabin
Are you failing at being agile? #digitallabinAre you failing at being agile? #digitallabin
Are you failing at being agile? #digitallabinAntonio Peric-Mazar
 
Symfony 4: A new way to develop applications #ipc19
Symfony 4: A new way to develop applications #ipc19Symfony 4: A new way to develop applications #ipc19
Symfony 4: A new way to develop applications #ipc19Antonio Peric-Mazar
 
A year with progressive web apps! #webinale
A year with progressive web apps! #webinaleA year with progressive web apps! #webinale
A year with progressive web apps! #webinaleAntonio Peric-Mazar
 
The UI is the THE application #dpc19
The UI is the THE application #dpc19The UI is the THE application #dpc19
The UI is the THE application #dpc19Antonio Peric-Mazar
 
Symfony 4: A new way to develop applications #phpsrb
 Symfony 4: A new way to develop applications #phpsrb Symfony 4: A new way to develop applications #phpsrb
Symfony 4: A new way to develop applications #phpsrbAntonio Peric-Mazar
 
A year with progressive web apps! #DevConMU
A year with progressive web apps! #DevConMUA year with progressive web apps! #DevConMU
A year with progressive web apps! #DevConMUAntonio Peric-Mazar
 
Service workers are your best friends
Service workers are your best friendsService workers are your best friends
Service workers are your best friendsAntonio Peric-Mazar
 
Symfony4 - A new way of developing web applications
Symfony4 - A new way of developing web applicationsSymfony4 - A new way of developing web applications
Symfony4 - A new way of developing web applicationsAntonio Peric-Mazar
 
Build your business on top of Open Source
Build your business on top of Open SourceBuild your business on top of Open Source
Build your business on top of Open SourceAntonio Peric-Mazar
 
Lessons learned while developing with Sylius
Lessons learned while developing with SyliusLessons learned while developing with Sylius
Lessons learned while developing with SyliusAntonio Peric-Mazar
 
Drupal8 for Symfony developers - Dutch PHP
Drupal8 for Symfony developers - Dutch PHPDrupal8 for Symfony developers - Dutch PHP
Drupal8 for Symfony developers - Dutch PHPAntonio Peric-Mazar
 
Drupal8 for Symfony Developers (PHP Day Verona 2017)
Drupal8 for Symfony Developers (PHP Day Verona 2017)Drupal8 for Symfony Developers (PHP Day Verona 2017)
Drupal8 for Symfony Developers (PHP Day Verona 2017)Antonio Peric-Mazar
 
Maintainable + Extensible = Clean ... yes, Code!
Maintainable + Extensible = Clean ... yes, Code! Maintainable + Extensible = Clean ... yes, Code!
Maintainable + Extensible = Clean ... yes, Code! Antonio Peric-Mazar
 
A recipe for effective leadership
A recipe for effective leadershipA recipe for effective leadership
A recipe for effective leadershipAntonio Peric-Mazar
 
Building real time applications with Symfony2
Building real time applications with Symfony2Building real time applications with Symfony2
Building real time applications with Symfony2Antonio Peric-Mazar
 

More from Antonio Peric-Mazar (20)

You call yourself a Senior Developer?
You call yourself a Senior Developer?You call yourself a Senior Developer?
You call yourself a Senior Developer?
 
Using API Platform to build ticketing system #symfonycon
Using API Platform to build ticketing system #symfonyconUsing API Platform to build ticketing system #symfonycon
Using API Platform to build ticketing system #symfonycon
 
Using API platform to build ticketing system (translations, time zones, ...) ...
Using API platform to build ticketing system (translations, time zones, ...) ...Using API platform to build ticketing system (translations, time zones, ...) ...
Using API platform to build ticketing system (translations, time zones, ...) ...
 
Are you failing at being agile? #digitallabin
Are you failing at being agile? #digitallabinAre you failing at being agile? #digitallabin
Are you failing at being agile? #digitallabin
 
Symfony 4: A new way to develop applications #ipc19
Symfony 4: A new way to develop applications #ipc19Symfony 4: A new way to develop applications #ipc19
Symfony 4: A new way to develop applications #ipc19
 
A year with progressive web apps! #webinale
A year with progressive web apps! #webinaleA year with progressive web apps! #webinale
A year with progressive web apps! #webinale
 
The UI is the THE application #dpc19
The UI is the THE application #dpc19The UI is the THE application #dpc19
The UI is the THE application #dpc19
 
Symfony 4: A new way to develop applications #phpsrb
 Symfony 4: A new way to develop applications #phpsrb Symfony 4: A new way to develop applications #phpsrb
Symfony 4: A new way to develop applications #phpsrb
 
A year with progressive web apps! #DevConMU
A year with progressive web apps! #DevConMUA year with progressive web apps! #DevConMU
A year with progressive web apps! #DevConMU
 
Service workers are your best friends
Service workers are your best friendsService workers are your best friends
Service workers are your best friends
 
Progressive Web Apps are here!
Progressive Web Apps are here!Progressive Web Apps are here!
Progressive Web Apps are here!
 
Symfony4 - A new way of developing web applications
Symfony4 - A new way of developing web applicationsSymfony4 - A new way of developing web applications
Symfony4 - A new way of developing web applications
 
Build your business on top of Open Source
Build your business on top of Open SourceBuild your business on top of Open Source
Build your business on top of Open Source
 
Lessons learned while developing with Sylius
Lessons learned while developing with SyliusLessons learned while developing with Sylius
Lessons learned while developing with Sylius
 
Drupal8 for Symfony developers - Dutch PHP
Drupal8 for Symfony developers - Dutch PHPDrupal8 for Symfony developers - Dutch PHP
Drupal8 for Symfony developers - Dutch PHP
 
Drupal8 for Symfony Developers (PHP Day Verona 2017)
Drupal8 for Symfony Developers (PHP Day Verona 2017)Drupal8 for Symfony Developers (PHP Day Verona 2017)
Drupal8 for Symfony Developers (PHP Day Verona 2017)
 
Drupal8 for Symfony Developers
Drupal8 for Symfony DevelopersDrupal8 for Symfony Developers
Drupal8 for Symfony Developers
 
Maintainable + Extensible = Clean ... yes, Code!
Maintainable + Extensible = Clean ... yes, Code! Maintainable + Extensible = Clean ... yes, Code!
Maintainable + Extensible = Clean ... yes, Code!
 
A recipe for effective leadership
A recipe for effective leadershipA recipe for effective leadership
A recipe for effective leadership
 
Building real time applications with Symfony2
Building real time applications with Symfony2Building real time applications with Symfony2
Building real time applications with Symfony2
 

Recently uploaded

Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Software Coding for software engineering
Software Coding for software engineeringSoftware Coding for software engineering
Software Coding for software engineeringssuserb3a23b
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptrcbcrtm
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 

Recently uploaded (20)

Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Software Coding for software engineering
Software Coding for software engineeringSoftware Coding for software engineering
Software Coding for software engineering
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.ppt
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 

Building APIs in an easy way using API Platform

  • 1. Pre-setup • Go to: https://github.com/Locastic/webcampzg-api-platform • Follow instructions • If you already did this, than: • git fetch --all • $ git pull • $ docker-compose exec php composer install
  • 2.
  • 3. Building APIs in an easy way using API Platform Antonio Perić-Mažar 04.10.2018., #webcampzg
  • 4. “API Platform is the most advanced API platform, in any framework or language.”
  • 5. “API Platform is the most advanced API platform, in any framework or language.” Fabien Potencier, SymfonyCon 2017
  • 6. Antonio Perić-Mažar CEO, Software Developer antonio@locastic.com @antonioperic
  • 7. Locastic • We help clients create amazing web and mobile apps (since 2011) • mobile development • web development • UX/UI • Training and Consulting • Shift Conference, Symfony Croatia • www.locastic.com t: @locastic
  • 8.
  • 9. We are hiring! • Symfony mid/senior developer • React (javascript) mid/senior developer • posao@locastic.com
  • 11. The web has changed • Javascript web apps are standard (SPA) • Users spend more time on using mobile devices than desktop or TV. • Linked Data and the semantic web are a reality
  • 12.
  • 13. APIs are the heart of this new web • Central point to access data (R/W data) • Encapsulate business logic • Same data and same features for desktops, mobiles, TVs and etc • It is stateless (PHP Sessions make horizontal scaling harder)
  • 14. Client Apps • HTML5 (SPA), mobile apps, TVs, Cars etc. • Holds all the presentation logic • Is downloaded first (SPA, shell model) • Queries the API to retrieve and modify data using asynchronous requests • Is 100% composed of HTML, JavaScript and assets (CSS and etc) • Can be hosted on a CDN
  • 15.
  • 16. Immediate benefits • Speed (even on mobile) • Scalability and robustness • Development comfort • Long term benefits
  • 18. HTTP + REST + JSON • Work everywhere • Lightweight • Stateless • HTTP has a powerful caching model • Extensible (JSON-LD, Hydra, Swagger, HAL…) • High quality tooling
  • 19. HATEOAS / Linked Data • Hypermedia as the Engine of Application State • Hypermedia: IRI as identifier • Ability to reference external data (like hypertext links) • Auto discoverable <=> Generic clients
  • 20.
  • 21. JSON-LD (JSON for Linked Data) • Standard: W3C recommandation (since 2014) • Machine readable data • Easy to use: looks like a typical JSON document • Already used by Gmail, GitHub, BBC, Microsoft, US gov… • Compliant with technologies of the semantic web: RDF, SPARQL, triple store… • Good for SEO
  • 22. Hydra • Describe REST APIs in JSON-LD • = write support • = auto-discoverable APIs • = standard for collections, paginations, errors, filters • Draft W3C (Work In Progress)
  • 23. { "@context": "/contexts/Book", "@id": "/books/2", "@type": "http://schema.org/Book", "id": 2, "isbn": "9790070863971", "description": "A long but very interesting story about REST and asyncio.", "author": "The life!", "title": "X", "publicationDate": "2002-01-29T00:00:00+00:00" }
  • 24. {  "@context": "contexts/Errors",  "@type": “hydra:Error”, “hydra:title”: “An error occurred”, “hydra:description”: “Not found” }
  • 25. { "@context": "/contexts/Book", "@id": "/books", "@type": "hydra:Collection", "hydra:member": [ { "@id": "/books/2", "@type": "http://schema.org/Book", "id": 2, "isbn": "9790070863971", "description": "A long but very interesting story about REST and asyncio.", "author": "The life!", "title": "X", "publicationDate": "2002-01-29T00:00:00+00:00" }, … { "@id": "/books/31", "@type": "http://schema.org/Book", "id": 31, "isbn": "9791943452827", "description": "Tempora voluptas ut dolorem voluptates. Provident natus ipsam fugiat est ipsam quia. Sint mollitia sed facere qui sit. Ad iusto molestias iusto autem laboriosam nulla earum eius.", "author": "Miss Gladyce Nader I", "title": "Voluptas doloremque esse dolor qui illo placeat harum voluptatem.", "publicationDate": "1970-10-11T00:00:00+00:00" } ], "hydra:totalItems": 125, "hydra:view": { "@id": "/books?page=1", "@type": "hydra:PartialCollectionView", "hydra:first": "/books?page=1", "hydra:last": "/books?page=5", "hydra:next": "/books?page=2" } }
  • 26.
  • 27. API Platform: the promise • Fully featured API supporting Swagger + JSON-LD + Hydra + HAL in minutes • An auto generated doc • Convenient API spec and test tools using Behat • Easy authentication management with JWT or OAuth • CORS and HTTP cache • All the tools you love: Doctrine ORM, Monolog, Swiftmailer...
  • 28. API Platform <3 Symfony • Built on top of Symfony full-stack • Install any existing SF bundles • Follow SF Best Practices • Use your Symfony skills • Can be used in your existing SF app • (Optional) tightly integrated with Doctrine
  • 29. Features • CRUD • Filters • Serializations groups and relations • Validation • Pagination • Sorting • The event system • Content Negation • Extensions • HTTP and reverse proxy caching • Invalidation-based HTTP caching • JS Admin apps • GraphQL support • And basically everything needed to build modern APIs
  • 30. — 82 — 90 — 8090——
  • 34. Setup $ git fetch --all $ git pull $ docker-compose up -d $ docker-compose exec php composer install
  • 35. Book 
 id: int isbn: string(13) title: string (255) abstract: text publicationDate: date averageReviewRate: float author_id: int Author 
 id: int firstname: string (255) lastname: text birthday: date Review 
 id: int author: string (255) review: text rate: datetime book_id: int createdAt: datetime
  • 36. #1 Task CRUD for Author, Book, Review resources
  • 37. CRUD <?php namespace AppEntity; class Author { private $id; private $firstName; private $lastName; // ... } # api/config/packages/api_platform/ author.yaml resources: AppEntityAuthor:~
  • 38.
  • 40.
  • 41.
  • 42.
  • 43. {   "@context": "http://schema.org",   "@type": "FlightReservation",   "reservationNumber": "RXJ34P",   "reservationStatus": "http://schema.org/Confirmed",   "underName": {     "@type": "Person",     "name": "Eva Green"   },   "reservationFor": {     "@type": "Flight",     "flightNumber": "110",     "airline": {       "@type": "Airline",       "name": "United",       "iataCode": "UA"     },     "departureAirport": {       "@type": "Airport",       "name": "San Francisco Airport",       "iataCode": "SFO"     },     "departureTime": "2017-03-04T20:15:00-08:00",     "arrivalAirport": {       "@type": "Airport",       "name": "John F. Kennedy International Airport",       "iataCode": "JFK"     },     "arrivalTime": "2017-03-05T06:30:00-05:00"   } }
  • 44. Using schema.org in Api Platform resources: AppEntityFlightReservation: iri: 'http://schema.org/FlightReservation'
  • 45. Using schema.org in Api Platform resources: AppEntityFlightReservation: iri: 'http://schema.org/FlightReservation' properties: status: iri: 'http://schema.org/reservationStatus'
  • 46. Operations • API Platform Core relies on the concept of operations. Operations can be applied to a resource exposed by the API. From an implementation point of view, an operation is a link between a resource, a route and its related controller. • There are two types of operations: • Collection operations act on a collection of resources. By default two routes are implemented: POST and GET. • Item operations act on an individual resource. 3 default routes are defined GET, PUT and DELETE.
  • 47.
  • 48. Your turn! #1 Task - create resources
  • 49. Your turn! #2 Task - add validation
  • 52. Your turn! #3 Task - order by, subresource
  • 53. Filters • If Doctrine ORM support is enabled, adding filters is as easy as registering a filter service in your api/config/services.yml file and adding an attribute to your resource configuration. • Filters add extra conditions to base database query • Useful filters for the Doctrine ORM are provided with the library. You can also create custom filters that would fit your specific needs.
  • 54. Filters • Search filter (partial, start, end, exact, ipartial, iexact) • Date filter (?property[<after|before>]=value ) • Boolean filter (?property=[true|false|1|0]) • Numeric filter (?property=int|bigint|decimal) • Range filter (?property[lt]|[gt]|[lte]|[gte]|[between]=value) • Order filter (?order[property]=<asc|desc>) • … • Custom filters
  • 55. Filters examples # AppBundle/Resources/config/api_resources/resources.yml resources: AppBundleEntityPlayer: # ... attributes: filters: ['player.search', 'player.order'] AppBundleEntityMatch: # ... attributes: filters: ['match.date'] services: player.search_filter: parent: 'api_platform.doctrine.orm.search_filter' arguments: [ { id: 'exact', email: 'exact', firstName: 'partial' } ] tags: [ { name: 'api_platform.filter', id: 'player.search' } ] match.date_filter: parent: 'api_platform.doctrine.orm.date_filter' arguments: [ { datetime: ~ } ] tags: [ { name: 'api_platform.filter', id: 'match.date' } ] player.order_filter: parent: 'api_platform.doctrine.orm.order_filter' arguments: [{ firstName: 'ASC', lastName: 'ACS', email: ~ }] tags: [{ name: 'api_platform.filter', id: 'player.order' }]
  • 56. Your turn! #4 Task - filters
  • 57. #5 Task Add serialization & deserialization groups to Player
  • 58. Serialization Groups • API Platform Core allows to choose which attributes of the resource are exposed during the normalization (read) and denormalization (write) process. It relies on the serialization (and deserialization) groups feature of the Symfony Serializer component. • allows to specify the definition of serialization using XML, YAML, or annotations.
  • 60. <?php namespace AppEntity; use FOSUserBundleModelUser as BaseUser; use SymfonyComponentSerializerAnnotationGroups; class Player extends BaseUser { /** * @var int */ protected $id; /** * @Groups({"player_read", "player_write"}) */ private $firstName; /** * @Groups({"player_read", "player_write"}) */ private $lastName; /** * @Groups({"player_read", "player_write"}) */ protected $email; // ... } # UserBundle/Resources/api_resources/resources.yml resources: AppEntityPlayer: attributes: normalization_context: groups: ['player_read'] denormalization_context: groups: ['player_write']
  • 61. Using Different Serialization Groups per Operation # UserBundle/Resources/api_resources/resources.yml resources: AppEntityPlayer: itemOperations: get: method: 'GET' normalization_context: groups: ['player_read', 'player_extra'] put: method: 'PUT' delete: method: 'DELETE' attributes: normalization_context: groups: ['player_read'] denormalization_context: groups: ['player_write']
  • 63. #6 Task Create event subscriber for posting new Review
  • 65. // src/AppBundle/EventSubscriber/MatchEventSubscriber.php class MatchEventSubscriber implements EventSubscriberInterface { private $matchHelper; public function __construct(MatchHelper $matchHelper) { $this->matchHelper = $matchHelper; } public static function getSubscribedEvents() { return [ KernelEvents::VIEW => [['addWinner', EventPriorities::POST_VALIDATE]], ]; } public function addWinner(GetResponseForControllerResultEvent $event) { $match = $event->getControllerResult(); $method = $event->getRequest()->getMethod(); if(!$match instanceof Match || $method !== 'POST') { return; } $winner = $this->matchHelper->getWinner($match); $match->setWinner($winner); } }
  • 67. Your turn! #7 Task - Virtual property
  • 69. Update progressive web app • docker-compose exec client generate-api-platform-clien • Follow instructions
  • 70. JSON Web Token (JWT) • Lightweight and simple authentication system • Stateless: token signed and verified server-side then stored client-side and sent with each request in an Authorization header • Store the token in the browser local storage
  • 71.
  • 72.
  • 73. API and JWT Integration • We need to install and configure • LexikJWTAuthenticationBundle • JWTRefreshTokenBundle
  • 74.
  • 75. Pagination # app/config/config.yml api_platform: # ... collection: pagination: items_per_page: 30 # Default value client_items_per_page: true # Disabled by default items_per_page_parameter_name: itemsPerPage # Default value client_enabled: true # optional enabled_parameter_name: pagination # optional page_parameter_name: _page # optional
  • 76. Operations • API Platform Core relies on the concept of operations. Operations can be applied to a resource exposed by the API. From an implementation point of view, an operation is a link between a resource, a route and its related controller. • There are two types of operations: • Collection operations act on a collection of resources. By default two routes are implemented: POST and GET. • Item operations act on an individual resource. 3 default routes are defined GET, PUT and DELETE.
  • 77. Custom operation class Match { private $id; /** * @Groups({"match_read"}) */ private $datetime; /** * @Groups({"match_read", "match_write"}) */ private $playerOnePoints; /** * @Groups({"match_read", "match_write"}) */ private $playerTwoPoints; /** * @Groups({"match_read", "match_write"}) */ private $playerOne; /** * @Groups({"match_read", "match_write"}) */ private $playerTwo; /** * @Groups({"match_read"}) */ private $winner; /** * @Groups({"match_read"}) */ private $result; }
  • 78. Custom operationclass Match { private $id; /** * @Groups({"match_read"}) */ private $datetime; /** * @Groups({"match_read", "match_write"}) */ private $playerOnePoints; /** * @Groups({"match_read", "match_write"}) */ private $playerTwoPoints; /** * @Groups({"match_read", "match_write"}) */ private $playerOne; /** * @Groups({"match_read", "match_write"}) */ private $playerTwo; /** * @Groups({"match_read"}) */ private $winner; /** * @Groups({"match_read"}) */ private $result; } class MatchController extends Controller { /** * @param Match $data * * @return Match */ public function getMatchAction($data) { $result = $data->getPlayerOne() . ' ' . $data->getPlayerOnePoints().':' .$data->getPlayerTwoPoints() . ' ' . $data->getPlayerTwo(); $data->setResult($result); return $data; } }
  • 79. Custom operation class Match { private $id; /** * @Groups({"match_read"}) */ private $datetime; /** * @Groups({"match_read", "match_write"}) */ private $playerOnePoints; /** * @Groups({"match_read", "match_write"}) */ private $playerTwoPoints; /** * @Groups({"match_read", "match_write"}) */ private $playerOne; /** * @Groups({"match_read", "match_write"}) */ private $playerTwo; /** * @Groups({"match_read"}) */ private $winner; /** * @Groups({"match_read"}) */ private $result; } class MatchController extends Controller { /** * @param Match $data * * @return Match */ public function getMatchAction($data) { $result = $data->getPlayerOne() . ' ' . $data->getPlayerOnePoints().':' .$data->getPlayerTwoPoints() . ' ' . $data->getPlayerTwo(); $data->setResult($result); return $data; } } # app/config/routing.yml get_match: path: /api/v1/matches/{id}.{_format} methods: ['GET'] defaults: _controller: AppBundle:Match:getMatch _api_resource_class: AppBundleEntityMatch _api_item_operation_name: get
  • 80. Extensions • API Platform Core provides a system to extend queries on items and collections. • Custom extensions must implement the ApiPlatformCoreBridgeDoctrineOrmExtensionQuery CollectionExtensionInterface and / or the ApiPlatformCoreBridgeDoctrineOrmExtensionQuery ItemExtensionInterface interfaces, to be run when querying for a collection of items and when querying for an item respectively.
  • 81. class GetPlayersExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface { public function applyToItem( QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, string $operationName = null, array $context = [] ) { $this->addWhere($queryBuilder, $resourceClass, $operationName); } public function applyToCollection( QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null ) { $this->addWhere($queryBuilder, $resourceClass, $operationName); } private function addWhere(QueryBuilder $queryBuilder, string $resourceClass, string $operationName = null) { if ($resourceClass != Player::class || $operationName != 'get') { return; } $rootAlias = $queryBuilder->getRootAliases()[0]; $queryBuilder->andWhere( $queryBuilder->expr()->eq($rootAlias.'.enabled', ':enabled') )->setParameter('enabled', true); } }
  • 82. services: app.extension.get_players: class: AppBundleDoctrineORMExtensionGetPlayersExtension public: false tags: - { name: api_platform.doctrine.orm.query_extension.collection, priority: 9 } - { name: api_platform.doctrine.orm.query_extension.item }
  • 83. Per Resource Authorization Mechanism namespace AppBundleEntity;   use ApiPlatformCoreAnnotationApiResource; use DoctrineORMMapping as ORM;   /** * @ApiResource( *     attributes={"is_granted"="has_role('ROLE_ADMIN')"}, *     itemOperations={ *         "get"={"method"="GET", "is_granted"="object.getOwner() == user"} *     } * ) * @ORMEntity */ class Secured {     /**      * @ORMColumn(type="integer")      * @ORMId      * @ORMGeneratedValue(strategy="AUTO")      */     public $id;       /**      * @ORMColumn(type="text")      */     public $owner;
  • 86. Specs and tests with Behat Behat and its Behatch extension make testing and API easy. # features/put.feature Scenario: Update a resource When I send a "PUT" request to "/people/1" with body: """ { "name": "Kevin" } """ Then the response status code should be 200 And the response should be in JSON And the header "Content-Type" should be equal to "application/ld+json" And the JSON should be equal to: """ { "@context": "/contexts/Person", "@id": "/people/1", "@type": "Person", "name": "Kevin", "address": null } """
  • 87. More features • ReactJS Based Admin generator • A React/Redux Webapp Generator • AngularJS app bootstrap • Symfony Flex support • Brand new docker setup (with varnish)
  • 88. More features • JSONAPI support • MongoDB native • GraphQL support
  • 90. QnA? Please rate my talk https://joind.in/talk/d03f0