FriendsOfSymfony / FOSRestBundle

This Bundle provides various tools to rapidly develop RESTful API's with Symfony
http://symfony.com/doc/master/bundles/FOSRestBundle/index.html
MIT License
2.79k stars 703 forks source link

look into supporting JSON API #452

Closed lsmith77 closed 9 years ago

lsmith77 commented 11 years ago

http://jsonapi.org

dupuchba commented 11 years ago

Nice use of JSON to enhance hypermedias. What are you plans of implementation of it and do you have any idea what work needs to be done?

lsmith77 commented 11 years ago

i have no immediate plans to work on it .. just put it here so that its not forgotten and in the hopes that someone else picks it up.

dupuchba commented 11 years ago

@lsmith77 ok :), I am ready to participate if someone take the lead of it. Right now I have no idea where to start.

lsmith77 commented 11 years ago

I guess a start could be building a Symfony Standard edition fork that (re-)builds one of the examples from the ember.js community and seeing what is currently missing.

stof commented 11 years ago

I think the read part can already be achieved using FSCHateosBundle and JMSSerializerBundle (and returning the appropriate data in your controller). the update part requires work as the json patch format needs to be parsed and converted into an update of the object.

awildeep commented 11 years ago

Keep in mind http://jsonapi.org/ is still a work in progress:

"This media type is still a work in progress, and we are extremely open to feedback and proposals for improvement. That said, implementation work has already begun, and we value good working systems over perfect vaporware."

That being said if this can be implemented properly, FOSRestBundle will truly help developers support Ember-data (Outside of this ticket the only active support I have seen is from the Ruby and Python communities).

I think two big keys here will be making the documentation, and keeping the implementation simple. I've been attempting to implement something of my own, and failing miserably as of late. I have high hopes for this however, and I am willing to try and help where ever I can (time permitting).

awildeep commented 11 years ago

I've been going through the pains of trying to implement a simple one to many relationship. Spent pretty much all day attempting to simulate the docs, and it is not as easy as it may seem. There is an incredible amount of labor involved, and I fear I may end up writing a LOT of custom code. I am struggling coming up with common code that could ease this pain yet. I am open for suggestions, but at this point I fear this implementation is just not worth the effort given the current state of existing REST, Serializer, and HATEOS bundles.

lsmith77 commented 11 years ago

This needs to be driven from the ORM/ODM metadata which then needs to be combined with the metadata in FSCHateoasBundle. Is there information missing on the ORM/ODM side?

awildeep commented 11 years ago

As far as the read side goes; I am fairly sure that the ORM/ODM should have all the information it needs with the possible exception of the relationship data required to build the HATEOS links (HATEOS will know the relationship, but not the URL path to the target REST API).

This is the first time i've really looked at any of the internals for the REST bundle, so I am definitely working a bit uphill.

lsmith77 commented 11 years ago

The key thing to look at is the view layer. However I think a lot of this will actually end up being done inside the Serializer. This is exactly what FSCHateosBundle takes as the integration point. As a result you might actually want to focus on that Bundle for now. Here is a PR to integrate it with FOSRestBundle https://github.com/FriendsOfSymfony/FOSRestBundle/pull/327 .. as you can see it works in principle but the integration is not done in a very efficient manner. If you could wrap that up it would be a huge step forward for this topic.

/cc @willdurand @adrienbrault

j commented 11 years ago

I can say after developing a full "restful api" from scratch using the HAL / Hateos specs, I wish I would have come across http://jsonapi.org much sooner b/c it makes way more sense in most cases. HAL / Hateos complicates things a bit... and I had to sit down with front-end people all the time b/c they we're confused.

j commented 11 years ago

granted, i only skimmed through the http://jsonapi.org stuff.... but i liked the small amount of what i saw and it seemed simple and dumbed down.

koemeet commented 10 years ago

Also looking for something like this, I am currently working/trying on creating a bundle which follows the jsonapi spec using JMS Serializer. Currently trying to figure out how to add data to the top-level. Anybody also working on a solution to support jsonapi?

mvrhov commented 10 years ago

IMO you should connect with @willdurand and @adrienbrault. They have a library that currently supports json+hal and are looking into also supporting other formats.

koemeet commented 10 years ago

Thanks, I see they are already on it, will try to help them out. :)

skqr commented 9 years ago

Hey, guys. I built a HATEOAS library / bundle that supports the full spec of JSON-API on top of a Symfony 2 with full Doctrine 2 entity mappings. It also incorporates RAML into the mix.

Thought you might want to check it out.

koemeet commented 9 years ago

@skqr Wow, looks good. But, why doesn't it integrate with JMS Serializer? A lot of people are using this when building there API's. Also when using this you are tight to use JSON API right? You cannot easily switch to XML or another format? The approach of HateoasBundle of @willdurand is very flexible (uses the JMS serializer also). What I like about your library is that you have sorting etc. automatically working when using Doctrine. Looks good overall, but I don't think it would integerate very well with popular existing bundles and projects.

skqr commented 9 years ago

Thanks, @steffenbrem =)

Absolutely. The project is quite opinionated. It requires you to use RAML, Doctrine 2, some Symfony 2 components - and JSON. Here's why.

I tried the JMS Serializer a number of times, and it simply was not built for the task. At least currently, and at least as far as I tried, it couldn't handle the kind of complex flattened and referenced serialization that JSON-API proposes.

I started the project attempting to implement HAL, and I originally intended to start with a fork of @willdurand's project.

I tried this for about a week. Then JSON-API hit me like a bucket of ice. It really blew my mind. It addresses several of today's most popular API's gravest errors in a slick and elegant manner.

So then I tried to make JSON-API happen along with the JMS Serializer and Will's lib, but that wasn't happening either. That's when I realized that a different, more focused approach, might fit my intentions better.

Abstractions might happen later, but will probably target things like the web framework (e.g. Laravel) or the specific ORM (e.g. Eloquent). This is definitely a RAML + JSON-API HATEOAS project.

I also love what the guys at MuleSoft are doing with RAML. I hear one of their tools lets you generate a JavaScript SDK for your API from your RAML definitions, and will soon be able to handle the other popular langs.

koemeet commented 9 years ago

@skqr Ah I've been there too. Here is a Gist of the serializer I wrote for JMS Serializer and the library of @willdurand. It supports linked resources, links etc. Not the whole json-api spec (but I don't need the whole spec, yet). https://gist.github.com/steffenbrem/ebfe0f07fe7b1df93b54. It is hacky in some sort, but it is still experimental for me.

It is currently optimized to work with Ember Data, but I try to follow JSON API as closely as possible.

Here is a screenshot of an example response that my serializer creates:

I don't know if this would help you ;) But I understand that you created your own solutions for this, you need a deeper understanding of the libraries before you can deal with the complex stuff JSON-API comes with.

That last thing you said, is very interesting haha. But I like how Ember data handles stuff. Easy to implement your JSON-API in it :+1: Good work man!

skqr commented 9 years ago

Oh, that was you! :smiley_cat:

Yeah, I was originally using your snippet as a base. Took it from here. It was a great help then!

Ember is quite cool. We're using it, as a matter of fact. This lib I made is the mini framework on top of which the APIs in the company I'm with will run. Clients will either be PHP SDKs or Ember apps.

The first client is a hybrid mobile app that's hitting the markets sometime next week. We were not too happy with the adapter JSON-API suggests, though. We're likely going to make our own soon.

It's not that I don't appreciate the flexible possibilities that JMS provides. It's just that the current design will never allow you to implement something like JSON-API, either comfortably or otherwise.

The main issue is resource relationship expansion. If you check out the example app using ?include=some-existing-relationship you'll see what I mean. That's the golden ticket.

The GOintegro lib supports any depth of recursive relationship expansion, so you can do stuff like this.

/some-resource?include=some-relationship,some-other-relationship.some-relationship-of-the-relationship.some-rel-of-the-rel-of-the-rel,yet-another-rel&fields[primary-resource-type]=some-field,some-other-field&fields[some-relationship-type]=yet-another-field&page=3

Seriously. All of that is supported.

willdurand commented 9 years ago

@steffenbrem I like your JsonApiSerializer class, would probably be a nice contribution to Hateoas.

koemeet commented 9 years ago

@skqr I am not so sure, JMS does a pretty good job on the serialization/deserialization part. Of course, you need to move the functionalities like sorting and including embedded resources with the include param somewhere else. But if you only support JSON-API, then your library simply rocks ;)

@willdurand Sure, I was thinking about creating a PR for this library. I need to write proper tests for this and clean stuff a bit up. What do you think about functionality like include and sorting as @skqr described. Do you want something like this as a part of the Hateoas library. Currently I've implemented the sorting stuff using the ParamFetcher which provides auto documentation with NelmioApiDocBundle, which is nice. But I haven't given it much tought yet on how to create a reusable component for this in your Hateoas library.

Also my current implementation gets its relation (linked) key from the ClassTypeResolver, I simply camelcase the class name in there :P, does the job for me now. If you want to make this configurable we should look into abstracting the Hateoas some more as @Alabme describes in this PR.

skqr commented 9 years ago

@steffenbrem, it's your class that got me rolling :smile_cat:

@willdurand's amazing post and projects too, obviously.

I'd love to see how this PR progresses.

Keep rocking, guys.

steveklabnik commented 9 years ago

Hey there! I just wanted to let you know that JSON API has hit RC3, and we'd like client libraries to start implementing it like it was 1.0, as a final check that we're good for 1.0. So hopefully that can inform the discussion here a bit.

https://github.com/json-api/json-api/issues/484

amenophis commented 9 years ago

@lsmith77: I can start working on this, it is an interresting topic ! How can we start ?

ghost commented 9 years ago

@amenophis : you will be a hero if you accomplish this!

silverqx commented 9 years ago

I have read whole json api spec now and it will not be as simple as it looks, there are many complicated scenarios and this spec is really extensive, but I hope we will have some implementation in near future, because I really like this new fresh spec.

esistgut commented 9 years ago

Is anyone working on this? JSON API hit the 1.0 stable and Ember Data just pushed the first stable release using it.

lsmith77 commented 9 years ago

not that I know of .. would be awesome!

koemeet commented 9 years ago

I am currently working on this, trying to get it out for public. I inspired most of it from the Hateoas bundle from willdurand.

For example, this is how you would configure the JSON-API serializer for your data models (later on it can also support XML of YAML, since I use jms/metadata to abstract the metadata):

/**
 * @Hateoas\Resource(type="posts")
 *
 * @author Steffen Brem <steffenbrem@gmail.com>
 */
class Post
{
    /**
     * @Hateoas\Id
     */
    protected $id;

    /**
     * @var string
     */
    protected $title;

    /**
     * @var string
     */
    protected $description;

    /**
     * @Hateoas\HasMany(includeByDefault=true)
     */
    protected $comments;

    // ...
}

What I am working on now is a seperate bundle, that will integrate with FOSRestBundle. I think that is the best approach for this. I hope I can make my work public soon :+1:

koemeet commented 9 years ago

I am not sure though if it needs to be another HateoasBundle or if I should just use JsonApiBundle and make it only for JSON-API.

silverqx commented 9 years ago

Hi,

from my point of view this is the way which I would also went. I really like how the FOSRestBundle works. I think that the best name for your bundle would be JsonApiBundle and only one think which will do, will be to work with JSON API, by FOSRestBundle way.

This problem could be accomplished by so many ways. I prefer to use and extend the FOSRestBundle and to use and inspire by the HateoasBundle regarding the work with links.

When you will have working bundle which will be compatible with JSON API v1, so you can work on better abstraction of the code and other enhancements.

You can use many code from Hateoas library, because there is really good code which handles links and mappings between entities and serialization ( through annotations ).

This is how I'm looking on this enhancement.

And about this unassuming line:

I hope I can make my work public soon :+1:

I'm really impatient how it will be implemented. ;-)

koemeet commented 9 years ago

@szachara I will put something public today, for now I am only working with an AnnotationDriver. Currently I've got some basic JSON-API serialization going with FOSRestBundle. You can mix anything with it, as you can see is the title attribute of a post annotated with @JMS\SerializedName("tiiitel"), so you can still use JMS features in it.

Here is a simple output from the serializer that I wrote of a basic Post > Comment relationship:

{
    "data": [
        {
            "type": "posts",
            "id": 1,
            "attributes": {
                "tiiitel": "My post",
                "description": "This is the first post"
            },
            "relationships": {
                "comments": {
                    "data": [
                        {
                            "type": "comments",
                            "id": 1
                        }
                    ]
                }
            }
        },
        {
            "type": "posts",
            "id": 2,
            "attributes": {
                "tiiitel": "My second post",
                "description": "This is the second post"
            },
            "relationships": {
                "comments": {
                    "data": [
                        {
                            "type": "comments",
                            "id": 1
                        }
                    ]
                }
            }
        },
        {
            "type": "posts",
            "id": 3,
            "attributes": {
                "tiiitel": "My third post",
                "description": "This is the third post"
            },
            "relationships": {
                "comments": {
                    "data": []
                }
            }
        }
    ],
    "included": [
        {
            "type": "comments",
            "id": 1,
            "attributes": {
                "title": "This is a comment title",
                "body": "My body"
            }
        }
    ]
}
silverqx commented 9 years ago

Great start, I have not found any error in serialized output, already now it's valid JSON API output. Of course a links objects are missing, but when a relationships object contains data object ( resource linkage) , so links are optional. And I absolutely understand that this is the output of a development preview.

You can mix anything with it, as you can see is the title attribute of a post annotated with @JMS\SerializedName("tiiitel"), so you can still use JMS features in it.

This is very important.

koemeet commented 9 years ago

If anyone wants to discuss about this topic, I created a public repo, which I will soon fill with my work that I have done. See: https://github.com/steffenbrem/JsonApiBundle

silverqx commented 9 years ago

:+1:

lsmith77 commented 9 years ago

ok .. closing the ticket as there is now a Bundle for this