JSON API


JSON api is making our api calls in efficient way. We can do all fetching data operations as we need, and can achieve CRUD operations in simple and easy way with json api calls.
This minimizes the amount of data and round trips needed when making API calls.

The JSON API specification defines how resources are structured. This structure helps in normalizing how you consume the API.

For example : to make api calls to resource articles with a simple get request,

GET /articles
HTTP/1.1
Accept: application/vnd.api+json

The response will be like below example.

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

We can get more idea by above example. Lets forward..

A compound document is a resource which includes the data of included relations. For example, when requesting an article as shown earlier it may include the data of the author so you don’t need a second call to fetch the author of the article.

This is awesome for a few reasons. Getting the full data of a resource you want to consume in one go is unheard of unless specific endpoints are programmed. On the server side of things, caching and invalidating a request like this is easy.

Just have a look at this example which returns a set of 1 document.

{
    "data": [{
        "type": "articles",
        "id": "1",
        "attributes": {
            "title": "JSON API paints my bikeshed!"
        },
        "links": {
            "self": "http://example.com/articles/1"
        },
        "relationships": {
            "author": {
                "links": {
                    "self": "http://example.com/articles/1/relationships/author",
                    "related": "http://example.com/articles/1/author"
                },
                "data": {
                    "type": "people",
                    "id": "9"
                }
            },
            "comments": {
                "links": {
                    "self": "http://example.com/articles/1/relationships/comments",
                    "related": "http://example.com/articles/1/comments"
                },
                "data": [{
                    "type": "comments",
                    "id": "5"
                }, {
                    "type": "comments",
                    "id": "12"
                }]
            }
        }
    }],
    "included": [{
        "type": "people",
        "id": "9",
        "attributes": {
            "first-name": "Dan",
            "last-name": "Gebhardt",
            "twitter": "dgeb"
        },
        "links": {
            "self": "http://example.com/people/9"
        }
    }, {
        "type": "comments",
        "id": "5",
        "attributes": {
            "body": "First!"
        },
        "relationships": {
            "author": {
                "data": {
                    "type": "people",
                    "id": "2"
                }
            }
        },
        "links": {
            "self": "http://example.com/comments/5"
        }
    }, {
        "type": "comments",
        "id": "12",
        "attributes": {
            "body": "I like XML better"
        },
        "relationships": {
            "author": {
                "data": {
                    "type": "people",
                    "id": "9"
                }
            }
        },
        "links": {
            "self": "http://example.com/comments/12"
        }
    }]
}


If you look at the included property you see all the related resources for the article. Every included document has a type property which defines which type of resource is returned and a link to the endpoint for the document.

It might feel weird to refer to the author relation in the article only by id and type and loading the related people resource from the included tag. But imagine when there are multiple articles referring to the same author, the document only includes the referred people once in the included data. Pretty efficient!

Inclusion of related resources
In the above example, the server includes all relations in the response, but you might not want this by default since this bloats the responses a bit. For this reason, the specification provides a way to specify what relations should be included in the response.

For example, if you only need the author relationship included you can just call the endpoint with the include request parameter. This will tell the server to only send the specified relation with the response.

GET /articles/1?include=author HTTP/1.1
Accept: application/vnd.api+json
If you need multiple relationships you separate the relations with a comma (,).
When defining the includes you can go even further and include nested relations. For example, you want comments, with the authors of the comments you can just include comments.author:

GET /articles/1?include=author,comments.author HTTP/1.1
Accept: application/vnd.api+json
This flexibility makes fetching the correct resources a breeze allowing you to tweak the results as needed.

Sparse fieldsets
When you are using compound documents your request could get large, fast. Especially when the included relationships contain a lot of data. Most of the time you do not need every single attribute defined in the resources but only want things like author names. JSON API provides sparse fieldsets for this use case.

You can specify the fields that are fetched by setting the fields request parameter. The format is fields[TYPE], so you can specify per resource type what fields you need.

GET /articles?include=author&fields[articles]=title,body&fields[people]=name HTTP/1.1
Accept: application/vnd.api+json
This call could include the title and body field from the articles resource and the name field from the people resource.

Other features
Servers may implement a few more features which are defined by the specification. These features are includes, sorting, pagination and filtering.

Sorting
If the server supports it, you can sort your records using the sort request parameter. Sorting is in ascending order by default, to sort descending you can prepend - to the field.

GET /articles?sort=-created,title HTTP/1.1
Accept: application/vnd.api+json
Pagination
If the server supports pagination it will supply a few extra meta attributes with pagination information. The server can decide how to paginate themselves, be it through an offset, or direct page numbers. An example of an implementation uses the required links to other pages and includes some metadata in the meta tag.

{
  links: {
    first: "http://example.com/articles?page=1",
    last: "http://example.com/articles?page=262",
    prev: "http://example.com/articles?page=261",
    next: null
  },
  meta: {
    current_page: 262,
    from: 3916,
    last_page: 262,
    per_page: 15,
    to: 3924,
    total: 3924
  }
}
Filtering
The spec says little about filtering, it just states there may be a parameter which is called filter which is used to fulfil filtering on the server. The implementation is specific for the server and can be anything.

Creating, Updating and Deleting resources
When you understand the structure of documents, creating and updating resources is a breeze. It uses the standard HTTP verbs to communicate the desired action of the request. GET for fetching, POST for creating, PATCH for (partial) updating and DELETE for deleting resources.

Creating resources
POST /photos HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "photos",
    "attributes": {
      "title": "Ember Hamster",
      "src": "http://example.com/images/productivity.png"
    },
    "relationships": {
      "photographer": {
        "data": { "type": "people", "id": "9" }
      }
    }
  }
}
This is an example of posting a new photo. As you notice the relationship is included in the request in the relationships property.

Updating resources
PATCH /articles/1 HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "To TDD or Not"
    }
  }
}
When updating a resource it will update the posted fields to the new values. Values that are not included in the request will not be updated.

Updating relationships
It is possible to update relationships in 2 ways. One way is to include the relation in the PATCH request. The same way as you have seen earlier. Another way is using the specific relationship endpoint.

PATCH /articles/1/relationships/author HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": { "type": "people", "id": "12" }
}
This call will update the to-one relationship on the article. If you want to delete the relation, you can pass null as the data.

If you want to update a to-many relation you can just send an array of relations to the endpoint. This will replace all members in the relation with the data you post.

PATCH /articles/1/relationships/tags HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": [
    { "type": "tags", "id": "2" },
    { "type": "tags", "id": "3" }
  ]
}
When clearing a to-many relation, just send an empty array as data.

Deleting resources
There isn’t much to say about deleting resources, you just send a DELETEcall to the endpoint.

DELETE /photos/1 HTTP/1.1
Accept: application/vnd.api+json
Learn more
If you want to learn more about the details of {json:api} and its usage, check out jsonapi.org. Their specification is quite clear, although there are a lot of features that are not mandatory for servers to implement. On their site, they also maintain a list of client and server implementations for you to get up and running quickly.

They are currently working on version 1.1 of the specification. It will be 100% backwards compatible with version 1.0, only adding new features, breaking nothing.

{json:api} <3
Hopefully, you’ve learned what makes this specification awesome. Personally, I love the structure, consistency and flexibility, this makes communicating with an API a lot easier. You always know what to expect, and don’t need loads of requests to get your data.

More References :
https://jsonapi.org/ 
https://github.com/json-api/json-api 
https://jsonplaceholder.typicode.com/

Source by Laravel News

Post a Comment

Post a Comment (0)

Previous Post Next Post