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

From REST to GraphQL

From REST to GraphQL

My talk, given at ElixirConf MX in Mexico City on November 18th, 2017. This 30 minute session highlighted basic features of GraphQL that are not present and/or have differing implementations across different flavors of REST. (Also touches on the features/use of Absinthe, the GraphQL toolkit for Elixir.)

Bruce Williams

November 18, 2017
Tweet

Other Decks in Technology

Transcript

  1. 2012-2015: Internal project (focused on mobile app APIs) Sep 2015:

    Open sourced spec working draft, Relay framework (based on React) Facebook Other client/server implementations followed, along with spec additions.
  2. query { allPosts(limit: 10) { title publishedAt author { name

    } body comments { author { name } body } } }
  3. {“data”: { “allPosts”: [ { “title”: “Using Absinthe”, “publishedAt”: “2017-11-17T00:20:00Z”,

    “author”: {“name”: “…”}, “body”: “…”, “comments” [ {“author”: {“name”: }, “body”: “…”}, … ] }, … ] }
  4. object :user do field :name, non_null(:string) field :posts, list_of(:post), resolve:

    … end object :post do field :title, non_null(:string) field :author, non_null(:author), resolve: … field :comments, list_of(:comment), resolve: … end … Macros!
  5. I’ve been using GraphQL quite heavily for the last 8

    months, primarily with JavaScript and I’ve found it to be a fairly tedious experience. I tried out an Elixir GraphQL library that's heavily based on macros and was almost immediately more productive—despite not even knowing the language. “ andrewingram, HN, 2016-05-08
  6. Query Subscribed Effect Response None Mutation Subscription Data Connection Data

    Later Data None None Data Modified triggers Manual push
  7. absinthe-graphql / absinthe absinthe-graphql / absinthe_plug absinthe-graphql / absinthe_ecto absinthe-graphql

    / absinthe_phoenix Client Support absinthe-graphql / dataloader absinthe-graphql / absinthe-socket absinthe-graphql / absinthe_relay
  8. REST is an inadequately shallow API standard for the needs

    of the modern web. “ Me, right now A few examples…
  9. URL REST: Read the documentation, if there is documentation. Hopefully

    it’s up to date. forward “/graphql”, Absinthe.Plug, schema: MyAppWeb.Schema http: //example.com/graphql
  10. “Resources” REST: Read the documentation, if there is documentation. Hopefully

    it’s up to date. query { __schema { types { name # kind, description, fields, etc } } }
  11. METHOD REST: GET, POST, PUT, and DELETE. You can always

    use POST. You can use GET for query operations.
  12. websockets REST: Undefined. While connection methods differ across GraphQL server

    implementations, you’re always passing GraphQL across them.
  13. Data Scope REST: Server defines the scope, may provide params

    (structure commonly undefined), and data is returned in… any structure. Clients declare the data that they want. The server returns the data (that it deems safe to) in the same structure
  14. Errors REST: Undefined, beyond HTTP Response Code ranges. May return

    JSON or free-form text error messages. {“errors”: [ {“message”: “”, “locations”: […], …}, … ]}
  15. Partial Data { “data”: { “categories”: [{“name”: “News”}, …], “user”:

    null }, “errors”: [ {“message”: “You are not authorized”, “path”: [“user”], …}, … ] } query { categories { name } user(id: “abc123”) { email } } REST: Undefined. Rarely done.
  16. Batching REST: Undefined; best path is usually to create a

    batch resource, and manually interact with it. { user1: user(id: “abc123”) { avatar(size: LARGE) { url } } user2: user(id: “abc321”) { avatar(size: LARGE) { url } } }
  17. Validation REST: Undefined. Do-it-yourself. All input is validated against the

    schema. If validation fails, no execution occurs and the errors are immediately returned.
  18. Scalars REST: Undefined. Do-it-yourself. String, ID, Float, Int, and others.

    You can create your own reusable scalar types if you define a way to parse and serialize it.
  19. Reusability REST: Undefined. URL templating? Maybe? query Chat($userId: ID!, $size:

    AvatarSize!) { user(id: $userId) { … Avatar } } fragment Avatar on User { avatar(size: $size) { url } }
  20. Aggregation REST: Undefined. Do it yourself. Field data can come

    from any data source. Database, external service, etc, and can be subject to data batching.
  21. Bandwidth REST: Undefined. Filtering params, custom API namespaces, etc. Because

    clients can query with a language, they can ask for as little or as much data as they want. This is especially good for low-bandwidth mobile.
  22. Notation REST: Undefined. Server controls style of notation. query {

    allPosts { … } } query { all_posts { … } } or
  23. versioning REST: Undefined. Common approach is separate URL namespace. object

    :user do field :name, non_null(:string) field :display_name, :string do deprecate “Use `name` instead” end end Or use separate schemas.
  24. EASE INTO IT REST + GraphQL REST using GraphQL for

    data (same app) GraphQL using REST (aggregating) GraphQL Absinthe.run/3