SlideShare ist ein Scribd-Unternehmen logo
1 von 88
Downloaden Sie, um offline zu lesen
Building APIs in an easy
way using API Platform
Paula Čučuk, Antonio Perić-Mažar

30.08.2017., #websc
Paula Čučuk
Software Developer
paula@locastic.com

@paulala_14
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 @locastic
Why API?
The web has changed
• Javascript webapps 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 AJAX
• 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
Immediate benefits
• Speed (even on mobile)
• Scalability and robustness
• Development comfort
• Long term benefits
• … and no, SEO and SMO are no more drawbacks
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
• The event system
• Content Negotion
• Extensions
• HTTP and reverse proxy caching
• JS Admin apps
• etc
Coding session
https://github.com/locastic/wscAPI2017
Ping Pong Score
keeping API
Setup
$ git fetch --all
$ git pull
$ php bin/console doctrine:schema:update —force
#1 Task
Player CRUD
CRUD
<?php
namespace AppBundleEntity;
use FOSUserBundleModelUser as BaseUser;
class Player extends BaseUser
{
protected $id;
private $firstName;
private $lastName;
protected $email;
// ...
}
# UserBundle/Resources/config/
api_resources/resources.yml
resources:
AppBundleEntityPlayer:~
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:
AppBundleEntityFlightReservation:
iri: 'http://schema.org/FlightReservation'
Using schema.org in Api Platform
resources:
AppBundleEntityFlightReservation:
iri: 'http://schema.org/FlightReservation'
properties:
status:
iri: 'http://schema.org/reservationStatus'
Your turn!
#1 Task
#2 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 AppBundleEntity;
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:
AppBundleEntityPlayer:
attributes:
normalization_context:
groups: ['player_read']
denormalization_context:
groups: ['player_write']
Using Different Serialization Groups
per Operation
# UserBundle/Resources/api_resources/resources.yml
resources:
AppBundleEntityPlayer:
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!
#2 Task
#3 Task
Implement Authentication using JSON
Web Token (JWT)
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
Your turn!
#3 Task
#4 Task
Create event subscriber for posting new
Player
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!
#4 Task
#5 Task
Match CRUD and pagination config
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
Your turn!
#5 Task
#6 Task
Add matchesWon number to GET
single Player endpoint
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
Your turn!
#6 Task
#7 Task
Create /me/matches endpoint which
returns all matches current user played.
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 }
Your turn!
#7 Task
#8 Task
Add some filters
Filters
• If Doctrine ORM support is enabled, adding filters is as easy as registering a filter
service in your app/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!
#8 Task
More features
Better documentation
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;
Subresources Support
/**
* @ApiResource
*/
class Product {
    /**
     * @ApiProperty(subcollection=true)
    */
    public $reviews;
}
/**
* http://example.com/products/1/reviews
*/
Cache invalidation is builtin
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)
Planned features for 2.2
• JSONAPI support
• MongoDB native
• GraphQL support
Thank you!
QA?

Weitere ähnliche Inhalte

Was ist angesagt?

OpenAPI Spec at Google (Open API Initiative Meetup on 2016-09-15)
OpenAPI Spec at Google (Open API Initiative Meetup on 2016-09-15)OpenAPI Spec at Google (Open API Initiative Meetup on 2016-09-15)
OpenAPI Spec at Google (Open API Initiative Meetup on 2016-09-15)Open API Initiative (OAI)
 
The REST And Then Some
The REST And Then SomeThe REST And Then Some
The REST And Then SomeNordic APIs
 
Another API-Blueprint, RAML and Swagger Comparison
Another API-Blueprint, RAML and Swagger ComparisonAnother API-Blueprint, RAML and Swagger Comparison
Another API-Blueprint, RAML and Swagger ComparisonSmartBear
 
API Docs Made Right / RAML - Swagger rant
API Docs Made Right / RAML - Swagger rantAPI Docs Made Right / RAML - Swagger rant
API Docs Made Right / RAML - Swagger rantVladimir Shulyak
 
Swagger for-your-api
Swagger for-your-apiSwagger for-your-api
Swagger for-your-apiTony Tam
 
API Description Languages: Which is the Right One for Me?
API Description Languages: Which is the Right One for Me?API Description Languages: Which is the Right One for Me?
API Description Languages: Which is the Right One for Me?Akana
 
virtual-2021-data.sql_.saturday.la-Building database interactions with users ...
virtual-2021-data.sql_.saturday.la-Building database interactions with users ...virtual-2021-data.sql_.saturday.la-Building database interactions with users ...
virtual-2021-data.sql_.saturday.la-Building database interactions with users ...Luis Beltran
 
API Design first with Swagger
API Design first with SwaggerAPI Design first with Swagger
API Design first with SwaggerTony Tam
 
Da 0 all'AI conversazionale usando Microsoft Azure
Da 0 all'AI conversazionale usando Microsoft AzureDa 0 all'AI conversazionale usando Microsoft Azure
Da 0 all'AI conversazionale usando Microsoft AzureMarco Parenzan
 
Building APIs with Node.js and Swagger
Building APIs with Node.js and SwaggerBuilding APIs with Node.js and Swagger
Building APIs with Node.js and SwaggerJeremy Whitlock
 
Designing APIs with OpenAPI Spec
Designing APIs with OpenAPI SpecDesigning APIs with OpenAPI Spec
Designing APIs with OpenAPI SpecAdam Paxton
 
API Developer Experience: Why it Matters, and How Documenting Your API with S...
API Developer Experience: Why it Matters, and How Documenting Your API with S...API Developer Experience: Why it Matters, and How Documenting Your API with S...
API Developer Experience: Why it Matters, and How Documenting Your API with S...SmartBear
 
Cloud Skills Challenge.pptx
Cloud Skills Challenge.pptxCloud Skills Challenge.pptx
Cloud Skills Challenge.pptxLuis Beltran
 
Level 3 REST Makes Your API Browsable
Level 3 REST Makes Your API BrowsableLevel 3 REST Makes Your API Browsable
Level 3 REST Makes Your API BrowsableMatt Bishop
 
Making Sense of Hypermedia APIs – Hype or Reality?
Making Sense of Hypermedia APIs – Hype or Reality?Making Sense of Hypermedia APIs – Hype or Reality?
Making Sense of Hypermedia APIs – Hype or Reality?Akana
 
Developing Faster with Swagger
Developing Faster with SwaggerDeveloping Faster with Swagger
Developing Faster with SwaggerTony Tam
 
OAuth 2.0 and Mobile Devices: Is that a token in your phone in your pocket or...
OAuth 2.0 and Mobile Devices: Is that a token in your phone in your pocket or...OAuth 2.0 and Mobile Devices: Is that a token in your phone in your pocket or...
OAuth 2.0 and Mobile Devices: Is that a token in your phone in your pocket or...Brian Campbell
 
OpenAPI 3.0, And What It Means for the Future of Swagger
OpenAPI 3.0, And What It Means for the Future of SwaggerOpenAPI 3.0, And What It Means for the Future of Swagger
OpenAPI 3.0, And What It Means for the Future of SwaggerSmartBear
 

Was ist angesagt? (19)

OpenAPI Spec at Google (Open API Initiative Meetup on 2016-09-15)
OpenAPI Spec at Google (Open API Initiative Meetup on 2016-09-15)OpenAPI Spec at Google (Open API Initiative Meetup on 2016-09-15)
OpenAPI Spec at Google (Open API Initiative Meetup on 2016-09-15)
 
The REST And Then Some
The REST And Then SomeThe REST And Then Some
The REST And Then Some
 
Another API-Blueprint, RAML and Swagger Comparison
Another API-Blueprint, RAML and Swagger ComparisonAnother API-Blueprint, RAML and Swagger Comparison
Another API-Blueprint, RAML and Swagger Comparison
 
API Docs Made Right / RAML - Swagger rant
API Docs Made Right / RAML - Swagger rantAPI Docs Made Right / RAML - Swagger rant
API Docs Made Right / RAML - Swagger rant
 
API for Beginners
API for BeginnersAPI for Beginners
API for Beginners
 
Swagger for-your-api
Swagger for-your-apiSwagger for-your-api
Swagger for-your-api
 
API Description Languages: Which is the Right One for Me?
API Description Languages: Which is the Right One for Me?API Description Languages: Which is the Right One for Me?
API Description Languages: Which is the Right One for Me?
 
virtual-2021-data.sql_.saturday.la-Building database interactions with users ...
virtual-2021-data.sql_.saturday.la-Building database interactions with users ...virtual-2021-data.sql_.saturday.la-Building database interactions with users ...
virtual-2021-data.sql_.saturday.la-Building database interactions with users ...
 
API Design first with Swagger
API Design first with SwaggerAPI Design first with Swagger
API Design first with Swagger
 
Da 0 all'AI conversazionale usando Microsoft Azure
Da 0 all'AI conversazionale usando Microsoft AzureDa 0 all'AI conversazionale usando Microsoft Azure
Da 0 all'AI conversazionale usando Microsoft Azure
 
Building APIs with Node.js and Swagger
Building APIs with Node.js and SwaggerBuilding APIs with Node.js and Swagger
Building APIs with Node.js and Swagger
 
Designing APIs with OpenAPI Spec
Designing APIs with OpenAPI SpecDesigning APIs with OpenAPI Spec
Designing APIs with OpenAPI Spec
 
API Developer Experience: Why it Matters, and How Documenting Your API with S...
API Developer Experience: Why it Matters, and How Documenting Your API with S...API Developer Experience: Why it Matters, and How Documenting Your API with S...
API Developer Experience: Why it Matters, and How Documenting Your API with S...
 
Cloud Skills Challenge.pptx
Cloud Skills Challenge.pptxCloud Skills Challenge.pptx
Cloud Skills Challenge.pptx
 
Level 3 REST Makes Your API Browsable
Level 3 REST Makes Your API BrowsableLevel 3 REST Makes Your API Browsable
Level 3 REST Makes Your API Browsable
 
Making Sense of Hypermedia APIs – Hype or Reality?
Making Sense of Hypermedia APIs – Hype or Reality?Making Sense of Hypermedia APIs – Hype or Reality?
Making Sense of Hypermedia APIs – Hype or Reality?
 
Developing Faster with Swagger
Developing Faster with SwaggerDeveloping Faster with Swagger
Developing Faster with Swagger
 
OAuth 2.0 and Mobile Devices: Is that a token in your phone in your pocket or...
OAuth 2.0 and Mobile Devices: Is that a token in your phone in your pocket or...OAuth 2.0 and Mobile Devices: Is that a token in your phone in your pocket or...
OAuth 2.0 and Mobile Devices: Is that a token in your phone in your pocket or...
 
OpenAPI 3.0, And What It Means for the Future of Swagger
OpenAPI 3.0, And What It Means for the Future of SwaggerOpenAPI 3.0, And What It Means for the Future of Swagger
OpenAPI 3.0, And What It Means for the Future of Swagger
 

Ähnlich wie 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
 
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
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
Advanced Web Development
Advanced Web DevelopmentAdvanced Web Development
Advanced Web DevelopmentRobert J. Stein
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1Mohammad Qureshi
 
Build an AI/ML-driven image archive processing workflow: Image archive, analy...
Build an AI/ML-driven image archive processing workflow: Image archive, analy...Build an AI/ML-driven image archive processing workflow: Image archive, analy...
Build an AI/ML-driven image archive processing workflow: Image archive, analy...wesley chun
 
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
 
Simple REST with Dropwizard
Simple REST with DropwizardSimple REST with Dropwizard
Simple REST with DropwizardAndrei Savu
 
Seattle StrongLoop Node.js Workshop
Seattle StrongLoop Node.js WorkshopSeattle StrongLoop Node.js Workshop
Seattle StrongLoop Node.js WorkshopJimmy Guerrero
 
How to Contribute to Apache Usergrid
How to Contribute to Apache UsergridHow to Contribute to Apache Usergrid
How to Contribute to Apache UsergridDavid M. Johnson
 
Spring 3 - An Introduction
Spring 3 - An IntroductionSpring 3 - An Introduction
Spring 3 - An IntroductionThorsten Kamann
 
RESTful API-centric Universe
RESTful API-centric UniverseRESTful API-centric Universe
RESTful API-centric UniverseTihomir Opačić
 
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013Kiril Iliev
 
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
 
Prototyping applications with heroku and elasticsearch
 Prototyping applications with heroku and elasticsearch Prototyping applications with heroku and elasticsearch
Prototyping applications with heroku and elasticsearchprotofy
 
Practical Use of MongoDB for Node.js
Practical Use of MongoDB for Node.jsPractical Use of MongoDB for Node.js
Practical Use of MongoDB for Node.jsasync_io
 
Frame - Feature Management for Productive Machine Learning
Frame - Feature Management for Productive Machine LearningFrame - Feature Management for Productive Machine Learning
Frame - Feature Management for Productive Machine LearningDavid Stein
 
12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocrat12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocratlinoj
 

Ähnlich wie Building APIs in an easy way using API Platform (20)

REST easy with API Platform
REST easy with API PlatformREST easy with API Platform
REST easy with 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 Platform
 
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
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Advanced Web Development
Advanced Web DevelopmentAdvanced Web Development
Advanced Web Development
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1
 
Build an AI/ML-driven image archive processing workflow: Image archive, analy...
Build an AI/ML-driven image archive processing workflow: Image archive, analy...Build an AI/ML-driven image archive processing workflow: Image archive, analy...
Build an AI/ML-driven image archive processing workflow: Image archive, analy...
 
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
 
Simple REST with Dropwizard
Simple REST with DropwizardSimple REST with Dropwizard
Simple REST with Dropwizard
 
Seattle StrongLoop Node.js Workshop
Seattle StrongLoop Node.js WorkshopSeattle StrongLoop Node.js Workshop
Seattle StrongLoop Node.js Workshop
 
How to Contribute to Apache Usergrid
How to Contribute to Apache UsergridHow to Contribute to Apache Usergrid
How to Contribute to Apache Usergrid
 
Spring 3 - An Introduction
Spring 3 - An IntroductionSpring 3 - An Introduction
Spring 3 - An Introduction
 
RESTful API-centric Universe
RESTful API-centric UniverseRESTful API-centric Universe
RESTful API-centric Universe
 
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
 
Node.js
Node.jsNode.js
Node.js
 
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
 
Prototyping applications with heroku and elasticsearch
 Prototyping applications with heroku and elasticsearch Prototyping applications with heroku and elasticsearch
Prototyping applications with heroku and elasticsearch
 
Practical Use of MongoDB for Node.js
Practical Use of MongoDB for Node.jsPractical Use of MongoDB for Node.js
Practical Use of MongoDB for Node.js
 
Frame - Feature Management for Productive Machine Learning
Frame - Feature Management for Productive Machine LearningFrame - Feature Management for Productive Machine Learning
Frame - Feature Management for Productive Machine Learning
 
12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocrat12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocrat
 

Mehr von 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
 
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
 
Building Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSBuilding Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSAntonio Peric-Mazar
 

Mehr von 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
 
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
 
Building Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSBuilding Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJS
 

Kürzlich hochgeladen

Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITmanoharjgpsolutions
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolsosttopstonverter
 
Data modeling 101 - Basics - Software Domain
Data modeling 101 - Basics - Software DomainData modeling 101 - Basics - Software Domain
Data modeling 101 - Basics - Software DomainAbdul Ahad
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...Bert Jan Schrijver
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptxVinzoCenzo
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...OnePlan Solutions
 
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdfPros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdfkalichargn70th171
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingShane Coughlan
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldRoberto Pérez Alcolea
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingShane Coughlan
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLionel Briand
 
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfEnhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfRTS corp
 
Zer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfZer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfmaor17
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shardsChristopher Curtin
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesKrzysztofKkol1
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecturerahul_net
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxRTS corp
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 

Kürzlich hochgeladen (20)

Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh IT
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration tools
 
Data modeling 101 - Basics - Software Domain
Data modeling 101 - Basics - Software DomainData modeling 101 - Basics - Software Domain
Data modeling 101 - Basics - Software Domain
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptx
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
 
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdfPros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository world
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and Repair
 
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfEnhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
 
Zer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfZer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdf
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecture
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 

Building APIs in an easy way using API Platform

  • 1. Building APIs in an easy way using API Platform Paula Čučuk, Antonio Perić-Mažar 30.08.2017., #websc
  • 3. Antonio Perić-Mažar CEO, Software Developer antonio@locastic.com @antonioperic
  • 4. 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 @locastic
  • 5.
  • 7.
  • 8. The web has changed • Javascript webapps are standard (SPA) • Users spend more time on using mobile devices than desktop or TV. • Linked Data and the semantic web are a reality
  • 9. 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)
  • 10. 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 AJAX • Is 100% composed of HTML, JavaScript and assets (CSS and etc) • Can be hosted on a CDN
  • 11.
  • 12. Immediate benefits • Speed (even on mobile) • Scalability and robustness • Development comfort • Long term benefits
  • 13. Immediate benefits • Speed (even on mobile) • Scalability and robustness • Development comfort • Long term benefits • … and no, SEO and SMO are no more drawbacks
  • 15. HTTP + REST + JSON • Work everywhere • Lightweight • Stateless • HTTP has a powerful caching model • Extensible (JSON-LD, Hydra, Swagger, HAL…) • High quality tooling
  • 16. 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
  • 17.
  • 18. 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
  • 19. Hydra • Describe REST APIs in JSON-LD • = write support • = auto-discoverable APIs • = standard for collections, paginations, errors, filters • Draft W3C (Work In Progress)
  • 20. { "@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" }
  • 21. {  "@context": "contexts/Errors",  "@type": “hydra:Error”, “hydra:title”: “An error occurred”, “hydra:description”: “Not found” }
  • 22. { "@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" } }
  • 23.
  • 24.
  • 25. 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...
  • 26. 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
  • 27. Features • CRUD • Filters • Serializations groups and relations • Validation • Pagination • The event system • Content Negotion • Extensions • HTTP and reverse proxy caching • JS Admin apps • etc
  • 30. Setup $ git fetch --all $ git pull $ php bin/console doctrine:schema:update —force
  • 32. CRUD <?php namespace AppBundleEntity; use FOSUserBundleModelUser as BaseUser; class Player extends BaseUser { protected $id; private $firstName; private $lastName; protected $email; // ... } # UserBundle/Resources/config/ api_resources/resources.yml resources: AppBundleEntityPlayer:~
  • 33.
  • 35.
  • 36.
  • 37.
  • 38. {   "@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"   } }
  • 39. Using schema.org in Api Platform resources: AppBundleEntityFlightReservation: iri: 'http://schema.org/FlightReservation'
  • 40. Using schema.org in Api Platform resources: AppBundleEntityFlightReservation: iri: 'http://schema.org/FlightReservation' properties: status: iri: 'http://schema.org/reservationStatus'
  • 42. #2 Task Add serialization & deserialization groups to Player
  • 43. 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.
  • 45. <?php namespace AppBundleEntity; 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: AppBundleEntityPlayer: attributes: normalization_context: groups: ['player_read'] denormalization_context: groups: ['player_write']
  • 46. Using Different Serialization Groups per Operation # UserBundle/Resources/api_resources/resources.yml resources: AppBundleEntityPlayer: 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']
  • 48. #3 Task Implement Authentication using JSON Web Token (JWT)
  • 49. 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
  • 50.
  • 51.
  • 52. API and JWT Integration • We need to install and configure • LexikJWTAuthenticationBundle • JWTRefreshTokenBundle
  • 53.
  • 54.
  • 56. #4 Task Create event subscriber for posting new Player
  • 58. // 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); } }
  • 60. #5 Task Match CRUD and pagination config
  • 61. 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
  • 63. #6 Task Add matchesWon number to GET single Player endpoint
  • 64. 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.
  • 65. 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; }
  • 66. 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; } }
  • 67. 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
  • 69. #7 Task Create /me/matches endpoint which returns all matches current user played.
  • 70. 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.
  • 71. 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); } }
  • 72. 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 }
  • 74. #8 Task Add some filters
  • 75. Filters • If Doctrine ORM support is enabled, adding filters is as easy as registering a filter service in your app/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.
  • 76. 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
  • 77. 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' }]
  • 81. 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;
  • 82. Subresources Support /** * @ApiResource */ class Product {     /**      * @ApiProperty(subcollection=true)     */     public $reviews; } /** * http://example.com/products/1/reviews */
  • 84. 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 } """
  • 85. More features • ReactJS Based Admin generator • A React/Redux Webapp Generator • AngularJS app bootstrap • Symfony Flex support • Brand new docker setup (with varnish)
  • 86. Planned features for 2.2 • JSONAPI support • MongoDB native • GraphQL support
  • 88. QA?