{json:api} - chris gchris-guzman.com/talks/jsonapi.pdf · #request authors with id of 1 or 2 get...

52
{json:api} @speaktochris @NexmoDev chris-guzman.com/jsonapi.pdf

Upload: others

Post on 23-May-2020

14 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

{json:api}@speaktochris@NexmoDev

chris-guzman.com/jsonapi.pdf

Page 2: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 3: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 4: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Ruby ! & Android "!

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 5: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

{json:api}A specification for building APIs in

JSON

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 6: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

{json:api}A specification for building APIs in

JSON(duh)

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 7: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

{json:api}Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 8: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

{json:api}Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 9: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

{"json":"api"}

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 10: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 11: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Why?

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 12: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 13: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

!

Page 14: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 15: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

- Minimize requests & data between clients & servers- Consistency, popular among consultancies

- Always backwards compatible- Stable 1.0, not dead

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 16: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

No, really

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 17: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

History

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 18: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

!+"+#$+%=

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 19: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 20: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Spec

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 21: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

- meta: a meta object that contains non-standard meta-information.

- errors: an array of error objects- OR -

- data: the document’s “primary data”

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 22: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Meta

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 23: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

{ "meta": { "count": "42", "copyright": "Copyright 2015 Example Corp.", "authors": [ "Yehuda Katz", "Steve Klabnik", "Dan Gebhardt", "Tyler Kellen" ] }}

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 24: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Errors

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 25: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

{ "errors": [ "id": "UUID", "status": "418", "code": "42", "title": "You're a teapot", "detail": "The object is not short nor stout", "links": { "about": "https://httpstatuses.com/418" }, "meta": { "email": "[email protected]" } ]}

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 26: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Data

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 27: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

GET /articlesAccept: application/vnd.api+json

GET /articles/1Accept: application/vnd.api+json

GET /articles/1/authorAccept: application/vnd.api+json

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 28: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

{ "data": { "type": "articles", "id": "1", "attributes": { "title": "Rails is Omakase" }, "relationships": {}, "links": { "self": "http://example.com/articles/1" }, }}

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 29: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Links

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 30: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

{"links": { "self": "/articles/1", "href": "http://example.com/articles/1" },}

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 31: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Relationships

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 32: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

{ "relationships": { "author": { "data": { "type": "people", "id": "9" }, "links": { "related": "/articles/1/author", "self": "/articles/1/relationships/author" } } }}

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 33: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

#Request comments with an articleGET /articles/1?include=comments

#Request authors & photos with an articleGET /articles/1?include=authors,photos

#Request comments as well as the author of each of those commentsGET /articles/1?include=comments.author

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 34: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

{ "data":[], "included": [ { "type": "people", "id": "11", "attributes": { "name": "Oli Rumbelow", "email": "[email protected]" } }, { "type": "photos", "id": "45", "attributes": { "url": "http://www.example.com/foobar", "height": 1080, "width": 1920 }}]}

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 35: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

#Request authors with id of 1 or 2GET /authors/?filter[id]=1,2

#Request authors who are aliveGET /authors?filter[alive]=true

#Request comments published after a dateGET /comments?filter[published_after]=1990-01-01

Note: JSON:API is agnostic about how the filter query parameter can be used.Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 36: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

#Request only the title, & status fieldsGET /articles?fields[articles]=title,status

#Request only the article's title & body fields#plus the name of the authorGET /articles/1?&fields[articles]=title,body\ include=author&fields[people]=name

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 37: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

{"data": [ { "type": "articles", "id": "3", "attributes": { "title": "NodeJS Best Practices", "status": "published" } }]}Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 38: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

#Sort articles alphabetically by titleGET /articles/?sort=title

#Sort authors by name, then lifeGET /authors?sort=name,alive

#Sort authors by reverse alphabetical order, then lifeGET /authors?sort=-name,alive

Note: JSON:API is agnostic about how the sort query parameter can be used.Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 39: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

#Get the third of 13 pages, one article at a timeGET /articles?page[number]=3&page[size]=1

"links": { "self": "http://example.com/articles?page[number]=3&page[size]=1", "first": "http://example.com/articles?page[number]=1&page[size]=1", "prev": "http://example.com/articles?page[number]=2&page[size]=1", "next": "http://example.com/articles?page[number]=4&page[size]=1", "last": "http://example.com/articles?page[number]=13&page[size]=1"}

Note: JSON:API is agnostic about how the page query parameter can be used.Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 40: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

GET /articles?include=comments,author &fields[people]=first_name,last_name &sort=-date

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 41: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

GET /articles?include=comments,author &fields[people]=first_name,last_name &sort=-date

» fetch all articles with their associated comments and authors

» Only be return the first and last names

» Sorted by date, most recent first

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 42: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

POST /photos{"data": { "type": "photos", "attributes": { "title": "Ember Hamster", "src": "http://example.com/images/productivity.png" }, "relationships": { "photographer": { "data": { "type": "people", "id": "9" } } } }}

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 43: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

PATCH /articles/1{"data": { "type": "articles", "id": "1", "attributes": { "title": "To TDD or Not", "text": "TLDR; It's complicated..." } }}

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 44: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

PATCH /articles/1/relationships/author

{ "data": { "type": "people", "id": "12" }}

PATCH /articles/1/relationships/tags

{ "data": [ { "type": "tags", "id": "2" }, { "type": "tags", "id": "3" } ]}

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 45: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

PATCH /articles/1/relationships/author{"data": null}

PATCH /articles/1/relationships/tags{"data": []}

DELETE /photos/1#empty body

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 46: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

JSON:API» Can take advantage of caching

» built on top of REST

vs GraphQL» Backed by heavier players

» GraphiQL UI

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 47: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 48: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Ok, maybe not the best analogy

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 49: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 50: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 51: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf

Page 52: {json:api} - Chris Gchris-guzman.com/talks/jsonapi.pdf · #Request authors with id of 1 or 2 GET /authors/?filter[id]=1,2 #Request authors who are alive GET /authors?filter[alive]=true

{json:api}@speaktochris@NexmoDev

chris-guzman.com/jsonapi.pdf

Better APIs with JSON:API - @speaktochris - chris-guzman.com/jsonapi.pdf