Slide 1

Slide 1 text

An introduction to Dan Gebhardt (@dgeb) Cerebris Corporation

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

"A Specification for Building APIs in JSON"

Slide 6

Slide 6 text

"A Specification for Fetching and Mutating a Graph of Data"

Slide 7

Slide 7 text

"A representation of resources and their relationships" Graph

Slide 8

Slide 8 text

application/vnd.api+json

Slide 9

Slide 9 text

Yehuda Katz @wycats Editors Dan Gebhardt @dgeb Gabe Sullice @gabesullice

Slide 10

Slide 10 text

History • 2013 - Initial draft released by Yehuda Katz • 2015 - v1.0 released • 2018 - v1.1 draft released • 2019 - v1.1 progress continues ...

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

"The JSON:API Specification" or "jsonapi.org"

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

" " " "

Slide 20

Slide 20 text

application/vnd.api+json

Slide 21

Slide 21 text

application/vnd.api+json

Slide 22

Slide 22 text

application/vnd.[org]+json

Slide 23

Slide 23 text

Sample of organizations that have either public APIs or public OSS projects that support JSON:API application/vnd.[org]+json

Slide 24

Slide 24 text

Sample of organizations that have either public APIs or public OSS projects that support JSON:API application/vnd.api+json

Slide 25

Slide 25 text

application/vnd.hal+json application/vnd.siren+json application/vnd.collection+json

Slide 26

Slide 26 text

application/???+json

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

Benefits

Slide 29

Slide 29 text

Benefits • Shared conventions • Shared tooling • Standards-based best practices • Plays well with others • Gradual adoption

Slide 30

Slide 30 text

Benefits • Shared conventions • Shared tooling • Standards-based best practices • Plays well with others • Gradual adoption

Slide 31

Slide 31 text

Shared conventions

Slide 32

Slide 32 text

Document structure + Processing rules Shared conventions

Slide 33

Slide 33 text

Document structure

Slide 34

Slide 34 text

{ "data": {} | [{}] | null, "included": {}, "links": {}, "meta": {}, "jsonapi": {}, "errors": [{}] } Top-level structure

Slide 35

Slide 35 text

{ "data": {} | [{}] | null, "included": {}, "links": {}, "meta": {}, "jsonapi": {}, "errors": [{}] } Top-level structure }All optional Specific combinations disallowed

Slide 36

Slide 36 text

{ "data": {} | [{}] | null } Top-level structure

Slide 37

Slide 37 text

{ "data": {} | [{}] | null, "included": {}, "links": {}, "meta": {} } Top-level structure

Slide 38

Slide 38 text

{ "errors": [{}] } Top-level structure

Slide 39

Slide 39 text

Primary data { "data": {} | [{}] | null }

Slide 40

Slide 40 text

{ "data": { "type": "article", "id": "123", "attributes": { "title": "Introduction to JSON:API", "published": "2019-10-11" } } }

Slide 41

Slide 41 text

{ "data": [{ "type": "article", "id": "123", "attributes": { "title": "Introduction to JSON:API", "published": "2019-10-11" } }, { "type": "article", "id": "124", "attributes": { "title": "Retrospective on ASC 2019", "published": "2019-10-15" } }] }

Slide 42

Slide 42 text

{ "type": "article", "id": "123" } Resource object

Slide 43

Slide 43 text

{ "type": "article", "id": "123" } Resource object }Also called a "Resource Identity Object" in its simplest form

Slide 44

Slide 44 text

{ "type": "article", "id": "123", "attributes": { // ... this article's attributes }, "relationships": { // ... this article's relationships }, "links": { // ... links to this article }, "meta": { // ... metadata about this article } }

Slide 45

Slide 45 text

{ "type": "article", "id": "123", "attributes": { "title": "Hello ASC 2019!" }, "relationships": { "author": { "links": { "self": "/articles/123/relationships/author", "related": "/articles/123/author" } } } }

Slide 46

Slide 46 text

{ "links": { "self": "/articles/123/relationships/author", "related": "/articles/123/author" } } Relationship object

Slide 47

Slide 47 text

{ "links": { "self": "/articles/123/relationships/author", "related": "/articles/123/author" }, "meta": { "created": "2019-10-15T18:13:25Z" } } Relationship object

Slide 48

Slide 48 text

{ "links": { "self": "/articles/123/relationships/author", "related": "/articles/123/author" }, "meta": { "created": "2019-10-15T18:13:25Z" }, "data": { "type": "person", "id": "123" } } Relationship object

Slide 49

Slide 49 text

{ "links": { "self": "/articles/123/relationships/author", "related": "/articles/123/author" }, "meta": { "created": "2019-10-15T18:13:25Z" }, "data": { "type": "person", "id": "123" } } Relationship object }Resource identity object(s), or "Linkage data"

Slide 50

Slide 50 text

{ "data": [{ "type": "article", "id": "123", "relationships": { "author": { "data": { "type": "person", "id": "abc" } } } }], "included": [{ "type": "person", "id": "abc", "attributes": { "name": "Dan Gebhardt" } }] } Compound Document

Slide 51

Slide 51 text

{ "data": [{ "type": "article", "id": "123", "relationships": { "author": { "data": { "type": "person", "id": "abc" } } } }], "included": [{ "type": "person", "id": "abc", "attributes": { "name": "Dan Gebhardt" } }] } Compound Document

Slide 52

Slide 52 text

{ "data": [ { "type": "article", "id": "1", "attributes": { "title": "JSON:API paints my bikeshed!" }, "relationships": { "author": { "data": { "type": "person", "id": "9" } }, "comments": { "data": [ { "type": "comments", "id": "5" } ] } } } ], // continued ... // ... continued "included": [ { "type": "person", "id": "9", "attributes": { "name": "Dan Gebhardt" } }, { "type": "comments", "id": "5", "attributes": { "body": "First!" }, "relationships": { "author": { "data": { "type": "person", "id": "9" } } } } ] }

Slide 53

Slide 53 text

{ "data": [ { "type": "article", "id": "1", "attributes": { "title": "JSON:API paints my bikeshed!" }, "relationships": { "author": { "data": { "type": "person", "id": "9" } }, "comments": { "data": [ { "type": "comments", "id": "5" } ] } } } ], // continued ... // ... continued "included": [ { "type": "person", "id": "9", "attributes": { "name": "Dan Gebhardt" } }, { "type": "comments", "id": "5", "attributes": { "body": "First!" }, "relationships": { "author": { "data": { "type": "person", "id": "9" } } } } ] }

Slide 54

Slide 54 text

Links { "links": { "self": "/articles/123" } }

Slide 55

Slide 55 text

Links { "links": { "self": "/articles/123", "doSomething": { "href": "/articles/123/doSomething", "meta": { "note": "POST to do something" } } } }

Slide 56

Slide 56 text

Links { "links": { "self": "/articles/123", "doSomething": { "href": "/articles/123/doSomething", "meta": { "note": "POST to do something" } } } } }Allowed links locations: • Top-level • Resource objects • Relationship objects • Error objects

Slide 57

Slide 57 text

{ "meta": { "whatever": "you want", "can": { "go": "in meta" } } } Metadata

Slide 58

Slide 58 text

{ "meta": { "whatever": "you want", "can": { "go": "in meta" } } } Metadata }Allowed metadata locations: • Top-level • Resource objects • Resource identity objects • Link objects • Error objects

Slide 59

Slide 59 text

Document structure + Processing rules Shared conventions

Slide 60

Slide 60 text

Processing rules

Slide 61

Slide 61 text

Opinionated HTTP usage

Slide 62

Slide 62 text

Opinionated HTTP usage • GET • POST • PATCH • DELETE • Resources • Relationships

Slide 63

Slide 63 text

• GET • POST • PATCH • DELETE • Resources • Relationships Opinionated HTTP usage

Slide 64

Slide 64 text

• GET • POST • PATCH • DELETE • Resources • Relationships Opinionated HTTP usage

Slide 65

Slide 65 text

Fetching GET /articles GET /articles/123 Note: URL Structure is not dictated by JSON:API

Slide 66

Slide 66 text

Graph Fetching GET /articles?include=author GET /articles?include=comments,author GET /articles?include=comments.author,author

Slide 67

Slide 67 text

Sparse Fieldsets GET /articles?fields=title,author GET /articles?include=author& fields[article]=title,author& fields[person]=name

Slide 68

Slide 68 text

Sorting GET /people?sort=age GET /people?sort=age,name GET /people?sort=-lastUpdated,name

Slide 69

Slide 69 text

Pagination GET /people?page[???]=x }Pagination strategy agnostic: • Page-based • Cursor-based

Slide 70

Slide 70 text

Filtering GET /people?filter[???]=x }Filtering strategy agnostic: • Simple, strict match • Nested conditions • Vertical-specific filtering

Slide 71

Slide 71 text

• GET • POST • PATCH • DELETE • Resources • Relationships Opinionated HTTP usage Documented at jsonapi.org

Slide 72

Slide 72 text

Benefits • Shared conventions • Shared tooling • Standards-based best practices • Plays well with others • Gradual adoption

Slide 73

Slide 73 text

Shared tooling

Slide 74

Slide 74 text

No content

Slide 75

Slide 75 text

Server • Swift • PHP • Node.js • Ruby • Python • Go • .NET • Java • JavaScript • Typescript • iOS • Ruby • PHP • Dart • Perl Client Libraries • Scala • Elixir • Haskell • Perl • Vala • Rust • Dart • Java • Android • R • Elm • .NET • Python • Elixir 74 93

Slide 76

Slide 76 text

Server netflix/fast_jsonapi google/jsonapi drupal/jsonapi cerebris/jsonapi-resources rails-api/active_model_serializers neomerx/json-api emberjs/data orbitjs/orbit crnk-project/crnk-framework jsonapi-ios/Spine reststate/Mobx reststate/Vuex Client Libraries

Slide 77

Slide 77 text

Benefits • Shared conventions • Shared tooling • Standards-based best practices • Plays well with others • Gradual adoption

Slide 78

Slide 78 text

Standards-based best practices

Slide 79

Slide 79 text

Composition of standards • HTTP (RFC7231) • JSON (RFC8259) • URI (RFC3986) • Profiles (RFC6906) • Web linking (RFC8288) • UUID (RFC4122) • And more ...

Slide 80

Slide 80 text

Composition of standards Evolution with those standards

Slide 81

Slide 81 text

Composition of standards Benefit from ecosystems that support those standards

Slide 82

Slide 82 text

Benefits • Shared conventions • Shared tooling • Standards-based best practices • Plays well with others • Gradual adoption

Slide 83

Slide 83 text

Plays well with others • OpenAPI • JSON Schema • JSON-LD • And more ...

Slide 84

Slide 84 text

Benefits • Shared conventions • Shared tooling • Standards-based best practices • Plays well with others • Gradual adoption

Slide 85

Slide 85 text

You MAY use feature X. Gradual adoption If you detect feature X, you MUST do A, B, and C.

Slide 86

Slide 86 text

Source: https://martinfowler.com/articles/richardsonMaturityModel.html Gradual adoption

Slide 87

Slide 87 text

JSON:API v1.1

Slide 88

Slide 88 text

JSON:API v1.1 • Profiles • Extensions • Expanded hypermedia controls

Slide 89

Slide 89 text

Profiles Extensions Specify meaning for members already reserved for users. Specify meaning for members reserved for the spec itself.

Slide 90

Slide 90 text

Profiles Extensions Negotiated with the `profile` media type parameter. Negotiated with the `ext` media type parameter.

Slide 91

Slide 91 text

Profiles Extensions May be ignored by servers. Must be supported or else error.

Slide 92

Slide 92 text

POST /bulk HTTP/1.1 Host: example.org Content-Type: application/vnd.api+json;ext="https://jsonapi.org/ext/atomic" Accept: application/vnd.api+json;ext="https://jsonapi.org/ext/atomic" { "atomic:operations": [{ "op": "add", "href": "/blogPosts", "data": { "type": "articles", "attributes": { "title": "JSON API paints my bikeshed!" } } }] } Extension: Atomic Operations Experimental

Slide 93

Slide 93 text

HTTP/1.1 200 OK Content-Type: application/vnd.api+json;ext="https://jsonapi.org/ext/atomic" { "atomic:results": [{ "data": { "links": { "self": "http://example.com/blogPosts/13" }, "type": "articles", "id": "13", "attributes": { "title": "JSON API paints my bikeshed!" } } }] } Extension: Atomic Operations Experimental

Slide 94

Slide 94 text

{ "atomic:operations": [{ "op": "add", "data": { "type": "authors", "id": "acb2ebd6-ed30-4877-80ce-52a14d77d470", "attributes": { "name": "dgeb" } } }, { "op": "add", "data": { "type": "articles", "id": "bb3ad581-806f-4237-b748-f2ea0261845c", "attributes": { "title": "JSON API paints my bikeshed!" }, "relationships": { "author": { "data": { "type": "authors", "id": "acb2ebd6-ed30-4877-80ce-52a14d77d470" } } } } }] } }Multiple linked operations Experimental

Slide 95

Slide 95 text

Expanded hypermedia controls

Slide 96

Slide 96 text

No content

Slide 97

Slide 97 text

Beyond JSON:API v1.1

Slide 98

Slide 98 text

Beyond JSON:API v1.1 • Optimize for HTTP/2/3 • More extensions! More experiments! • Focus on DX via tooling (e.g. spectral rulesets)

Slide 99

Slide 99 text

HTTP/1.1 Includes GET /articles?include=author GET /articles?include=comments,author GET /articles?include=comments.author,author

Slide 100

Slide 100 text

HTTP/2 Server Push GET /articles?serverPush=author GET /articles?serverPush=comments,author GET /articles?serverPush=comments.author,author Experimental

Slide 101

Slide 101 text

HTTP/2 Server Push Experimental

Slide 102

Slide 102 text

Resources

Slide 103

Slide 103 text

No content

Slide 104

Slide 104 text

No content

Slide 105

Slide 105 text

No content

Slide 106

Slide 106 text

No content

Slide 107

Slide 107 text

No content

Slide 108

Slide 108 text

An introduction to Dan Gebhardt (@dgeb) Cerebris Corporation

Slide 109

Slide 109 text

An introduction to Dan Gebhardt (@dgeb) Cerebris Corporation Thanks! jsonapi.org @jsonapi