REST vs GraphQL: illustrated examples with the API Platform framework

REST vs GraphQL: illustrated examples with the API Platform framework

GraphQL is an increasingly popular alternative to REST architectures for building web APIs.
The query language promoted by Facebook has undeniable advantages: retrieve exactly what the client need, limitation of the number of queries, strong typing, powerful and extremely well thought out syntax...
However, it also suffers from often underestimated problems including HTTP cache, logs, security or authentication, features that are the basis of the today's web stack. GraphQL is also a non-standard format that requires a specific parser.
In addition, modern REST-based hypermedia formats such as JSON-LD or JSON API have features very similar to those of GraphQL (and more advanced ones) while remaining compatible with the fundamentals of the web.

The API Platform framework, based on Symfony, makes it easy to create REST APIs (JSON-LD, JSON API, HAL ...) just like GraphQL.
After listing the advantages and disadvantages of different formats, we will study through different cases of frequent use when it is better to use GraphQL, REST or both in addition.

E66449b8260b07a1cf51c5ab5eaa8180?s=128

Kévin Dunglas

March 30, 2018
Tweet

Transcript

  1. REST vs GraphQL Illustrated examples using API Platform

  2. Kévin Dunglas Founder of Les-Tilleuls.coop Symfony Core Team (PropertyInfo, WebLink,

    Serializer, autowiring, PSR-7 Bridge…) API Platform creator @dunglas
  3. Les-Tilleuls.coop Self-managed company since 2011 100% owned by employees 25

    people, 97% growth in 2016 Hiring in Paris and Lille: jobs@les-tilleuls.coop
  4. The API Platform framework

  5. None
  6. or

  7. None
  8. JSON-LD+Hydra (default) OpenAPI (default) GraphQL JSONAPI HAL + API Problem

    YAML, JSON, CSV, XML Supported Formats
  9. None
  10. Install

  11. The Distribution $ docker-compose up

  12. None
  13. None
  14. None
  15. All components: API, Schema gen, Admin, Client gen PHP and

    JS Docker images, Docker Compose env Postgres server Varnish, invalidation-based cache mechanism enabled HTTPS and HTTP/2 dev reverse proxy Helm chart to deploy in Kubernetes clusters (GKE…) What’s Inside
  16. Alternative: use Flex $ composer create-project \ symfony/skeleton my-api $

    cd my-api $ composer req api $ php -S 127.0.0.1:8000 -t public
  17. • Only the API component • Minimalist

  18. Enabling the GraphQL Support

  19. Install GraphQL support $ composer req \ webonyx/graphql-php

  20. None
  21. None
  22. GraphQL?

  23. None
  24. None
  25. None
  26. None
  27. None
  28. A data query language Specifically designed for web APIs… …as

    an alternative to REST Open format with a formal specification Perfect as an API gateway (aggregate data from services) Released by Facebook in 2015 Service oriented GraphQL
  29. © graphql.org

  30. © graphql.org

  31. queries mutations subscriptions (❌ not supported in PHP) type system,

    introspection errors (limited) multiple queries in one request (parallelization) Main Features
  32. De-facto standard for GraphQL servers Created by Facebook for the

    Relay library Node (super type, like Object in Java) Object Identification: unique identifier across types Connections: structure for pagination Mutations format Server Specification
  33. Example: the GitHub API

  34. None
  35. None
  36. Defining REST

  37. An architectural style for web services Defined in Roy Fielding’s

    thesis in 2000 Leverage the HTTP protocol True REST APIs are hypermedia (HATEOAS) Resource oriented REpresentational State Transfer
  38. W3C Standards

  39. Map JSON properties to an ontology Perfect for hypermedia APIs

    W3C standard (2014), as HTML, CSS… Compatible with existing semantic web standards and tools (RDF, OWL, SPARQL, triple stores, Apache Jena…) JSON for Linked Data
  40. Global and open vocabulary Define types, properties and enumerations ~600

    types: Person, Place, Organization, Event… Extensible Preferred encoding: JSON-LD W3C community group started by Google, Microsoft, Yahoo and Yandex
  41. Format for interoperable, hypermedia APIs Built on top of JSON-LD,

    compatible with schema.org In-band API documentation Resources, properties, operations, collections, templated links (filters), pagination, errors Draft of a potential W3C specification (community group)
  42. Example: Google Knowledge Graph API

  43. None
  44. Alternative Formats

  45. Alternative Formats OpenAPI (formerly Swagger)

  46. Community format to build hypermedia web APIs Simpler and easier

    to implement than Hydra+JSON-LD… …but less powerful (no RDF nor schema.org compat) Pagination, filtering, sparse fieldsets, compound docs, errors… Limited type system, no introspection Experimental extensions
  47. API doc format (describe RESTful contracts) Path, operations, content negotiation…

    Type system built with JSON Schema Request/response formats up to you: JSON, XML… Can partially describe JSON-LD and JSONAPI OpenAPI (formerly Swagger)
  48. Schema and Types

  49. None
  50. None
  51. GraphQL Usage

  52. None
  53. None
  54. Describe the data that can be queried Expose operations (queries,

    mutations) Made the API auto-discoverable (in-band docs) Allow to develop smart clients (API agnostic) GraphQL Schema
  55. Hydra Documentation

  56. None
  57. Capabilities similar to GraphQL’s Schema Leverage RDF and OWL ()

    Describe API’s types and supported REST operations Unlike GraphQL: API interoperability at web scale (hypermedia) ability to use open vocabularies (schema.org) JSON-LD/Hydra Vocab
  58. None
  59. Alternative: OpenAPI

  60. Data fetching: REST

  61. new request

  62. Data fetching: GraphQL

  63. + REST compatibility (API Platform specific)

  64. Declarative and elegant query language The client tells exactly what

    it needs 1 query (vs N with REST) to retrieve all required data Solve under-fetching and over-fetching problem Require a specific query parser, but returns JSON No response/request parity: you cannot post a previously retrieved then updated document GraphQL
  65. Data fetching: Compound Docs

  66. None
  67. Solve the N requests problem The server is still rigid:

    the client’s request must be known Don’t solve the under/over-fetching problem
  68. Data fetching: Sparse Fieldsets

  69. None
  70. Solve the N requests problem Solve the under/over fetching problem

    Can be subject to problems with RDMS (more on this later) Less explicit and elegant than GraphQL but…
  71. PHP JavaScript

  72. Filtering

  73. None
  74. REST

  75. None
  76. GraphQL

  77. Alternative REST format Describe an advanced query language Batch support

    Not implemented (yet) in API Platform Alternative:
  78. Sorting

  79. None
  80. REST

  81. None
  82. GraphQL

  83. Pagination

  84. REST

  85. None
  86. GraphQL

  87. REST: configurable items per page

  88. Changing States

  89. REST Support for compound documents Ex: update both a book

    and an author in 1 request
  90. GraphQL

  91. None
  92. Logs

  93. REST

  94. GraphQL

  95. Caching

  96. GET responses are generated only 1 time, then served by

    Varnish Responses are tagged with IRIs (URLs) of resources they contain When a write operation occurs cached responses containing stale data are purged Support only REST (for now) API Platform Built-in Cache
  97. Most GraphQL clients use POST (=no HTTP cache) Even with

    GET: high cache miss rate Similar problem for sparse fieldsets If most requests are similar: A HTTP cache layer limits the over-fetching problem Cache Considerations
  98. Server application cache (ex: Doctrine data cache) HTTP server-side cache

    (ex: Varnish) HTTP client-side cache (ex: browser) Client application cache (ex: local storage) REST Cache Layers
  99. Server application cache (ex: Doctrine data cache) HTTP server-side cache

    (ex: Varnish) HTTP client-side cache (ex: browser) Client application cache (ex: local storage) GraphQL Cache Layers
  100. RDMS Performance

  101. API Platform tries to optimize SQL queries, (adds relevant joins),

    for both REST and GraphQL Dynamic requests (GraphQL, sparse fieldsets) will most likely not hit the indexes monitor frequent slow queries use more adapted DB: Neo4J, ElasticSearch… With GraphQL, request can quickly become huge RDMS Performance
  102. Security & Reliability

  103. Industry recommendations Out of the box implem by API Platform

    Very large history and research REST: OWASP SCS
  104. Fewer feedback and history Non-obvious security protection: timeout? maximum query

    depth? maximum query complexity? More sensitive to DDOS attacks GraphQL Security
  105. None
  106. (No) Versionning

  107. GraphQL promotes deprecation over real versioning Good practice with REST

    too: API evolution strategy JSON-LD/Hydra: document deprecation with OWL Not supported in API Platform yet (contrib? ❤) No Versionning
  108. Client-side

  109. GraphQL: great, mature low-level libraries for React Apollo Client (community)

    Relay (Facebook) Hydra: younger client-side ecosystem api-platform/api-doc-parser: low level doc parser api-platform/client-generator: PWA & native app generator (React, React Native, Vue.js) api-platform/admin: automatic React admin interface Client-side
  110. The Developper Ethical Responsibility

  111. Linked Data GraphQL Origin Scientific community Facebook Data access Open

    data Information silo Interop Global and built-in Partial Best suited for Decentralized systems (the world wide web) Centralized systems
  112. None
  113. Summary

  114. Awesome, elegant query language Perfect for: very dynamic or different

    clients Real-time support (but not in PHP) Ability to query unrelated data easily Limited HTTP compat (cache, logs, content negot…) Not easy to implement: parser, security, caching, perf… GraphQL
  115. Modern formats have similar features than GraphQL sparse fieldsets, batch

    endpoints (ODATA)… Mature and robust solution Leverage HTTP (cache, content-negotiation, logs, security…) REST
  116. Public and open API: REST Private API for dynamic clients:

    GraphQL API Platform: Create both with the same code The GraphQL API is compatible with Linked Data/REST Use Both?
  117. api-platform/api-platform @ApiPlatform Thanks! Now, the questions… api-platform.com

  118. Internals

  119. Design the API’s public data model as PHP classes API

    Platform creates an intermediate representation: resources, types, cardinalities, r/w, description… Metadata are used to: generate the schema (OpenAPI, Hydra, GraphQL…) (de)serialize data in the selected format (JSON-LD, GraphQL…) The Internals
  120. Interfaces to access and persist data (Doctrine, Mongo, Elastic…): DataProvider

    DataPersister Automatic registration of REST routes and GraphQL endpoint Serialization and validation rely on Symfony components REST: no controllers, pass thru a set of SF kernel event’s listeners Dependency Injection and service decoration everywhere The Internals (cont.)
  121. None