wearefractal / crudify

Mongoose CRUD generator
MIT License
75 stars 7 forks source link

Serve a HATEOAS-friendly root #4

Open erik-stephens opened 11 years ago

erik-stephens commented 11 years ago

Summary

As a consumer of an API, I would like an entry point to jump into, so that I can easily get a survey of the kinds of resources & relationships that are available.

Notes

yocontra commented 11 years ago

Already on the TODO:

I'm iffy on returning html content. Do you have any examples of large APIs doing this? In NodeJS I'm not sure what the performance would be converting a ~100K length JSON array to XML. Content negotiation might be better off as a plugin

Are there any standards for what should be returned on the root?

erik-stephens commented 11 years ago

I don't know of any api's that do this. When in doubt, I think about traditional web pages & browsers. I wouldn't prioritize this. It might be cool to say your api honors HATEOAS, but probably won't make much difference at the end of the day. And I guess it would be cool if I could dive into the content of an api, but there's already decent tooling for develpers to do that.

I do think the "wget for api's" might have some merit some day. I can imagine a consumer wanting a data dump. Instead of requesting a huge payload, they could crawl the api this way which might become a standard. With proper ETag headers, it might be a more efficient way of accomplishing that.

erik-stephens commented 11 years ago

Forgot to reply about the performance. Would paging the results alleviate your concerns?

yocontra commented 11 years ago

How would this work with the population? Nested tables?

erik-stephens commented 11 years ago

Not sure I understand. You referring to the optional populate request params? I was assuming that none of the generated url's would include those and that those would be discoverable via the links to the related entities and collections.

yocontra commented 11 years ago
GET /users?populate=boss

Content-Type: text/html

How does the response look?

yocontra commented 11 years ago
{
   "collections":[
      {
         "name":"users",
         "routes":[
            {
               "type":"collection",
               "methods":[
                  "post",
                  "get"
               ],
               "url":"/users"
            },
            {
               "type":"collection-static-method",
               "methods":[
                  "post",
                  "get"
               ],
               "url":"/users/search"
            },
            {
               "type":"single",
               "methods":[
                  "get",
                  "put",
                  "patch",
                  "delete"
               ],
               "url":"/users/:userId"
            },
            {
               "type":"single-instance-method",
               "methods":[
                  "post",
                  "get"
               ],
               "url":"/users/:userId/findWithSameName"
            },
            {
               "type":"single-with-populate",
               "methods":[
                  "get"
               ],
               "url":"/users/:userId/bestFriend"
            },
            {
               "type":"single-with-populate",
               "methods":[
                  "get"
               ],
               "url":"/users/:userId/friends"
            },
            {
               "type":"single-with-populate-many",
               "methods":[
                  "post"
               ],
               "url":"/users/:userId/friends"
            }
         ]
      }
   ]
}

How does this look for the JSON meta info for GET / and OPTIONS /? This data comes from the User model in test/fixtures/UserModel

erik-stephens commented 11 years ago

About the HTML details, I was assuming things like populate would not be used. All those auxilliary definitions and relationships can be discovered from the entity's page. The collections page would only show the columns/attributes. Entitiy IDs would be rendered as hyperlinks to the entity page. I think this strikes a good balance between useful while not getting overly complicated to implement.

erik-stephens commented 11 years ago

For the JSON details, I think that's looking good, although I would recommend publishing those details from the collection url (eg /users). The root can be as simple as a link to all the available collections.

yocontra commented 11 years ago

@erik-stephens Yeah I'll split each routes meta out next for GET /:collName/_meta and OPTIONS /:collName

Top-level has a list of routes/collections and each route will have the same info as well as the schema information