Yii2: Support for JSONAPI with Rest

Created on 25 Feb 2016  路  32Comments  路  Source: yiisoft/yii2

is there any plan to support JSONAPI? I'm working with Ember project and I can see the pain.
If no plan, does yii2 provide a way one can utilize to format API to JSONAPI? I want to be able to take advantage of CRUD provided by Yii yet support somehow JSONAPI
TIA

rest

Most helpful comment

I have created an implementation of JSON API specification for the Yii2 https://github.com/tuyakhov/yii2-json-api. It is currently working on a project in production. I would be glad to get any feedback.

All 32 comments

we currently do not have plans for this. Could you briefly summarize what needs to be done by yii to fully support/utilize JSONAPI?

Let me take time to summarize it in the morning.
Thanks!

Server content type support

  • Servers MUST send all JSON API data in response documents with the header Content-Type: application/vnd.api+json without any media type parameters.
  • Servers MUST respond with a 415 Unsupported Media Type status code if a request specifies the header Content-Type: application/vnd.api+json with any media type parameters.
  • Servers MUST respond with a 406 Not Acceptable status code if a request's Accept header contains the JSON API media type and all instances of that media type are modified with media type parameters.

That is for server. Next I will post for JSON document itself

  • A JSON object MUST be at the root of every JSON API request and response containing data. This object defines a document's "top level".
  • A document MUST contain at least one of the following top-level members:

    • data: the document's "primary data"
    • errors: an array of error objects
    • meta: a meta object that contains non-standard meta-information.

    The members data and errors MUST NOT coexist in the same document.


  • A document MAY contain any of these top-level members:


    • jsonapi: an object describing the server's implementation

    • links: a links object related to the primary data.

    • included: an array of resource objects that are related to the primary data and/or each other

  • The top-level links object MAY contain the following members:

    • self: the link that generated the current response document.
    • related: a related resource link when the primary data represents a resource relationship.
    • pagination links for the primary data.

    _The Resource_


  • Every resource object MUST contain an id member and a type member. The values of the id and type members MUST be strings.

  • In addition, a resource object MAY contain any of these top-level members:


    • attributes: an attributes object representing some of the resource's data.

    • relationships: a relationships object describing relationships between the resource and other JSON API resources.

    • links: a links object containing links related to the resource.

    • meta: a meta object containing non-standard meta-information about a resource that can not be represented as an attribute or relationship.

    • all included resources MUST be represented as an array of resource objects in a top-level included member.

_Example_

{
  "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"
    }
  }]
}

That is all I could try to summarize about JSONAPI. As you can see, a lot are optional and the format is used for post objects back and forth between API and Front end

most of this should already be possible with current rest implementation.

You are right. However it involves a lot of hacking around model/response which is not nice. Plus you loose the CRUD Yii provides!

If you can steer me in the right direction to make possible adding a switchable way (JSONAPI/Current implementation) I will try to write it and provide PR.

I have zero experience with JSONAPI so I do not know what needs to be done. I am going to work on API related things the next weeks so maybe I come accross JSONAPI too not sure yet though.

I will wait to see if you come across anything. Meanwhile I will try to poke around things see how hard it is to implement it in yii. Thank you for your time

you should be able to do this with our existing tools,
all you need is a custom Serializer class

JSONAPI is a separate standart therefore it must be implemented as a separate extension like it's done for Symfony, Laravel and other non-PHP frameworks.

@SilverFire
I would be happy to take a little time and write extension or whatever needed to make JSONAPI capabilities in Yii2 REST. But am not good at internals of Yii and not very good at design. So I will appreciate if someone takes the job and does it. If no one happen to have time now to do it, I will appreciate direction to Yii best design to plunge the Standard in.

Thanks for the links, I will take time to look at how they did it!

@fernandezekiel I don't think it is that easy unless you qualify your statement :)

i already have written a project of mine that works with ember and does comply partially with json API, atleast some of the response formats.
however i haven't fully read the JSONAPI spec... all i cared about for now is that the UI client works with it
you can start the project and add the specs there.

@fernandezekiel Can you share your experience? may be sample codes?

also check the relationships sections. I think it needs more than just data serialization. it needs extra actions to link/unlink data + support for nested resources. It may also need a different UrlRule class as suggested by @klimov-paul in https://github.com/yiisoft/yii2/issues/7878#issuecomment-86485350

Hi,

I am running into the same problem. If the JSON API isnt going to be supported soon, I would like to create my own API using the Slim Framework. Could anyone provide some advice as to how I might set up an API module to do this?

Many thanks!

From private discussions with @creocoder about this last year, I don't think JSONAPI is going to be easy to accomplish with the current API setup in Yii2 ... :-/

Hi,

I am implementing my own API, using Slim ;-)

And so what is the way forward? It will never get implemented? @acorncom

@mtangoo I don't speak for the core team, but we ended up finding that JSON-API was going to get fairly complicated with Yii2's setup. You might be able to use an alternate serializing system within Yii2 (Fractal is slowly improving their JSON-API serializer), but it doesn't match the spec yet ...

In addition I'm exploring https://github.com/tuyakhov/yii2-json-api
Let me see where I can get with it

Another thing that I found and not tried
https://github.com/neomerx/json-api/wiki

I think it's quicker to write your own using Slim....

what is that slim?

I don't want to learn something new at this time. I just does not have that time. Sorry

I have created an implementation of JSON API specification for the Yii2 https://github.com/tuyakhov/yii2-json-api. It is currently working on a project in production. I would be glad to get any feedback.

Great Thing its not complex to do. I will test it and feedback in one of these days. One question though, is there a reason to have both implements ResourceInterface and use ResourceTrait ? I think have a base model will save user from duplicating same code in each model. Something like

class JsonApiModel extends ActiveRecord implements ResourceInterface
{
    use ResourceTrait; 
}

or any other way that would prevent code duplication!

It is pretty much impossible to have a base model because of different types of ActiveRecord classes which could be different depending on type of database you use. Also it is not mandatory to use ResourceInterface only in ActiveRecord classes. You could use it pretty much everywhere. And it is up to you to create a base model you want.
Actually the basic idea is very close to what yii2 is using in base classes, for example yii\base\Arrayable interface and yii\base\ArrayableTrait trait.
So in your case when you create JsonApiModel which extends yii\db\ActiveRecord it means that JsonApiModel can be used only with RDBMS. What if you will need to use also yii\mongodb\ActiveRecord? Or you could want to return in your API data which is not stored in database at all. For example in login or reset password forms.

Boom! You just destroyed my argument in single go! Was I locked in some imaginary RDBM only world or what?

I think I can happily close the thread.
Thanks for your time and code!

Was this page helpful?
0 / 5 - 0 ratings