how should Hateoas be handled from frontend? - json

I have this question that has been going around through my head for a while. Lets suppose we have structured our project with backend and frontend on separate layers. So, from the frontend, we want to get a costumer, which comes on hal+json format:
GET /customers/1 HTTP/1.1
Accept: application/hal+json
{
"name": "Alice",
"links": [ {
"rel": "self",
"href": "http://localhost:8080/customer/1"
} {
"rel": "transactions",
"href": "http://localhost:8080/customer/1/transactions"
}]
}
Then, from the frontend i want to get all customer transactions. My question is: how should i get the url? should it be from the response? or should i build it internally?
if we go with first option, i think that maybe that wouldn't be elegant to iterate all links until we get that one we want. Also, there could happen the situation where we don't have the link of the request we want to do.
if we go with second option, i don't understand how to build that url if we don't actually have the ids. How could i create new customer transactions if hateoas replaces ids with links and i haven't got the object reference in the body anymore?
I thought that maybe service should support both application/hal+json(oriented to users) and application/json(oriented to clients) but i don't see that this is how is making it done generally.
What do you think?

Definitely the first option. Namely, since HATEOAS is a final stage of Richardson Maturity Model, clients are expected to follow the provided links, not to build the URLs by themselves:
The point of hypermedia controls is that they tell us what we can do
next, and the URI of the resource we need to manipulate to do it.
Rather than us having to know where to post our appointment request,
the hypermedia controls in the response tell us how to do it.
What benefits does this bring? I can think of at least two:
Simple upgrade of the REST API - server-side developers can change the URIs of the resources, without breaking the client-side code because clients just follow the provided links; additionally, server-side developers can easily add new links
Robustness - by following the links, client-side code would never try to access the broken links, misspelled links etc.
Q: Also, there could happen the situation where we don't have the link of the request we want to do?
It is up to API designer to ensure that all required links are provided. Front-end developer shouldn't worry about that.
See also:
Rest lesson learned - avoid hackable URLs

HATEOAS (Hypermedia as the Engine of Application State) is a constraint of the REST application architecture. You can have a look on Spring HATEOAS documentation for instance :
https://spring.io/understanding/HATEOAS
Another link about it using Spring and AngularJS is available here:
AngularJS and Spring HATEOAS tutorial
This one seems to be good enough and handles your use case.
Regards, André

Related

Should my API nest JSON data in a parent object?

I got called "unprofessional" today because I didn't nest my JSON response in a parent object.
GET /users/{id} responds with this:
{
"username":"atr217",
"age":35,
...
}
They expected this:
{
"user":{
"username":"atr217",
"age":35,
...
}
}
Or maybe this:
{
"status":200,
"message":"OK"
"data":{
"username":"atr217",
"age":35,
...
}
}
I've seen it done both ways. Is the best practice to wrap the data in a parent? If so, why? And what else goes in the parent?
I'm using SwaggerHub and OpenAPI 3, if that matters.
I found the correct Google search term: "envelope"
RESTful API Design Tips from Experience
“I do not like enveloping data. It just introduces another key to navigate a potentially dense tree of data. Meta information should go in headers.”
“One argument for nesting data is to provide two distinct root keys to indicate the success of the response, data and error . However, I delegate this distinction to the HTTP status codes in cases of errors.”
“Originally, I held the stance that enveloping data is not necessary, and that HTTP provided an adequate “envelope” in itself for delivering a response. However… I now recommend enveloping.”
When in my REST API should I use an envelope? If I use it in one place, should I always use it?
“HTTP is your envelope… Having said that, there is nothing wrong with having a descriptive body on a response”
Best Practices for Designing a Pragmatic RESTful API
“Don’t use an envelope by default, but make it possible when needed”
“We can future proof the API by staying envelope free by default and enveloping only in exceptional cases.”
“There are 2 situations where an envelope is really needed - if the API needs to support cross domain requests over JSONP or if the client is incapable of working with HTTP headers.”
“Envelope loving APIs typically include pagination data in the envelope itself. And I don’t blame them - until recently, there weren’t many better options. The right way to include pagination details today is using the Link header introduced by RFC 5988.”

REST/HATEOAS - Available methods in HAL links

I am looking at defining a REST API using HATEOAS. In particular, I find very interesting the concept of indicating for a given resource the actions that are available right now.
Some of the HATEOAS specifications include too much overhead for my needs, so I was looking at the HAL specification, as I find it very concise and practical:
{
_links: {
self: { href: "/orders/523" },
warehouse: { href: "/warehouse/56" },
invoice: { href: "/invoices/873" }
},
currency: "USD",
status: "shipped",
total: 10.20
}
However, links in HAL only contain a list of related resources, but not the available actions on them. As per the example above, am I allowed to cancel the order now, or not anymore? Some HAL examples solve this by using a specific URL for cancellations, and add a corresponding link in the response only if cancellation is possible:
"cancel": { "href": "/orders/523/cancel" }
But that is not very RESTful. Cancellations are not a resource. Cancellations are a DELETE of a resource, i.e.:
DELETE /orders/523
Is there a nice way to represent this with HAL, or should I use a different HATEOAS specification?
I am considering returning a "cancel" link with the same URL as self, but in this case the client would have to know that to cancel they have to use the DELETE verb, which is not really being described in the HATEOAS response.
self: { "href": "/orders/523" },
cancel: { "href": "/orders/523" }
Would this be the recommended approach as per HATEOAS / HAL? I understand HAL does not have any "method" parameter, and adding it myself would be against the HAL specification.
Some HAL examples solve this by using a specific URL for cancellations, and add a corresponding link in the response only if cancellation is possible
Yes. Just like web sites: if you want to alert the client to the possibility of reaching some other application state, you provide the client with a link, including the identifier for the resource involved.
But that is not very RESTful.
It may not be "RESTful", but it is certainly conforms to the REST architectural style.
Cancellations are a DELETE of a resource, i.e.: DELETE /orders/523
You are confusing the actions on the domain model with the actions on the integration model. What a REST API does is guide the client through a protocol to achieve some end; it is not a mapping of domain semantics onto HTTP.
Jim Webber phrased it this way:
The web is not your domain; it's a document management system. All of the HTTP verbs apply to the document management domain. URIs do NOT map onto domain objects -- that violates encapsulation. Work (ex: issuing commands to the domain model) is a side effect of managing resources.
One of the REST constraints is the uniform interface; in the case of HTTP, it means that all resources understand methods in a uniform way; DELETE means the semantics described in RFC 7231, section 4.3.5.
In other words, if I send the request
OPTIONS /x/y/z/foobar ...
and the response includes DELETE in the Allow header, then I know what it means. The side effects in your domain? I don't know anything about the side effects.
In the definition of DELETE, note the following
Relatively few resources allow the DELETE method -- its primary use is for remote authoring environments, where the user has some direction regarding its effect.
Anyway, you aren't really asking about DELETE, but about HAL
Is there a nice way to represent this with HAL, or should I use a different HATEOAS specification?
From what I can tell, the official way to do it is to document it with the link relation. In other words, instead of using "cancel" as the link relation, you use something like
https://www.rfc-editor.org/rfc/rfc5023#section-5.4.2
And then your consumers, if they want to discover what a link is for, can follow the relation to learn what is going on.
HAL Discuss: Why No Methods? has a lot of good information.
I like Mike Kelly's summary:
The idea is the available methods can be conveyed via the link
relation documentation and don't need to be in the json messages.
According to this article from LosTechies, in a CQRS perspective, Its accepted to use URLs such as: /orders/<id>/<command> and call these with PUT requests. So its OK to use a "cancel": { "href": "/orders/523/cancel" }.
However, if you absolutely want to use DELETE and you only use command links to modify your ressources (i.e. /orders/<id>/<command>) like proposed the article, why can't you just add a link such as "cancel": { "href": "/orders/523" } and deduct the HTTP verb?
I mean according to REST there is only 5 main verbs (GET, POST, PUT, PATCH and DELETE). We can't use POST on a URL such as /<ressource>/<id>, GET is already define as the "self" relation, we mentioned above that modifications (PUT) will be handled by command links (i.e. /<ressource>/<id>/<command>) and because we use command links there is no need to use PATCH. After that, the only option left is: DELETE.
It's not perfect, but it works and it doesn't break any convention.

Where to put forms / alternative views in a RESTful html app?

Let's assume an web application that for each URI presents a nice html view for GET requests and allows to update the underlying resource through POST/PUT/PATCH/WHATEVER.
How do I then expose various forms that actually allow performing such requests from the browser? And broader: assuming I have alternative views (possibly also HTML) for the same resource, where do I put those? Arguably, such forms can be considered alternative views, so having an answer to the broader question would be ideal.
Edit: To clarify, my question is not about pure data APIs serving JSON or whatnot, but about HTML apps such as Stackoverflow. For example you can get the collection of questions under /questions and this particular one at /questions/24696982 which makes sense. To get the form to add a new question, you will have to use /questions/ask, which I'm not sure is alright. And that form POSTs to /questions/ask/submit, which seems just plain wrong. Making a GET request to that URL yields a 404 (if anything it should be a 405). The form should be POSTing to /questions. Still I would like to know whether at least the URI for the form is considered acceptable in a RESTful system.
You have a website like, the one way to build a real RESTFull API is to split the frontend and the API - thats in my opinion the best way (some may disagree) - maybe some other don't think like this but lets say the frontend team got www.domain and your team for the API got api.domain.
GET api.domain/questions - Retrieves a list of tickets
GET api.domain/questions/12 - Retrieves a specific ticket
POST api.domain/questions - Creates a new ticket
PUT api.domain/questions/12 - Updates ticket #12
DELETE api.domain/questions/12 - Deletes ticket #12
PATCH api.domain/questions/12 - Partially updates ticket #12 #I only want to display that this also exists - i don't really use it...
AWESOME EDIT: As you can see also stackoverflow uses this method: api.stackexchange.com
So as you can see you can have these structure - but you also can have a form on www.domain/questions/ask and this form would send the request to api.domain/questions via POST. I want to refer to: https://thenewcircle.com/s/post/1221/designing_a_beautiful_rest_json_api_video its a really nice podcast you should have heard.
EDIT: (another point of view)
Another idea is that you can simply choose which content should come back (Json,XML,HTML) if your client sends you the right Accept-Header.
Example 1:
URL REQUEST ACCEPT HEADER RESPONSE
-----------------------------------------------------------------------------------------
domain/questions GET application/json all questions as json
domain/questions GET text/html the page as html with all questions
domain/questions/ask GET text/html Your html for to add a new question
domain/questions POST application/json Add a new new questions (this would be called from ./ask to add the new questions
domain/questions/ask GET application/json 404 Status-Code because on questions/ask you don't have implemented any resource
Example-2:
URL REQUEST ACCEPT HEADER RESPONSE
-----------------------------------------------------------------------------------------
domain/questions/12 GET application/json Shows the questions with the ID 12 as JSON
domain/questions/12 GET text/html Shows the HTML representation of your page
domain/questions/12/edit GET text/html Your html for to edit a the question
domain/questions/12 PUT application/json Updates the questions with the ID 12 // just to add the PATCH thing.. i don't really use it but if you don't update the whole object you could/should use PATCH instead of PUT :p
domain/questions/12/edit GET application/json 404 Status-Code because on questions/ask you don't have implemented any resource
Yesterday I told you about the first idea (which is - I think for using an api as a team (one for frontend and one team that develops the api - a better way) but as #jackweirdy commented (thanks for that - i then searched a lot and was looking at other podcasts from developer around the world and how they would do that) below it's really all up to you - it's your api and at the end you/your team will decide for one way. Hope this helps you or other that looking for how to build a API on a REST background.
The examples in the EDIT-Section would be (if I got it right) not like here on stackoverflow
This is something I've had trouble with myself, and which I don't think there's a right answer to.
Assuming I have an API exposing /people/:id, I generally reserve an endpoint for /people/new. a GET request to that url with Accept: text/html will return a form for creation, but anything else will throw a 404, since this page only exists for people in a web browser. The form on that page will then post to /people/ as you'd expect.
Similarly, if someone wants to edit an existing person, the form to do that might be served from /people/1/update, again HTML only.
If your API has that structure, then I think reserving keywords such as new or update is perfectly reasonable.
As far as I can understand your question, you want an application that :
displays HTML pages (and eventually other formats ?)
displays form views for creation of new elements or for update of existing ones
accept POST/PUT with url encoded data (sent by submitting above forms) to create of update those elements (and eventually other formats ?)
Ruby on Rails is a framework that is targetted as this kind of requirement. Extract from the guide Rails Routing from the Outside In :
HTTP Verb Path action used for
GET /photos index display a list of all photos
GET /photos/new new return an HTML form for creating a new photo
POST /photos create create a new photo
GET /photos/:id show display a specific photo
GET /photos/:id/edit edit return an HTML form for editing a photo
PUT /photos/:id update update a specific photo
DELETE /photos/:id destroy delete a specific photo
You can have HTML views for the actions index, new, show and edit.
Personally, I would recommend to add the following :
POST /photos/:id update update a specific photo
POST /photos/:id/delete destroy delete a specific photo
so that it would be simpler to update or delete elements via html forms.
All those paths are only Rails convention and are not imposed by REST but it gives a clean example of what can be done.
But it is quite easy to make an application following the same or slightly different conventions using other frameworks. Java + Spring MVC can do that very easily, with HTML views using JSP, Velocity, Thymeleaf or others, and the possibility of using JSON in input or output simply using HTTP headers or suffixes in URL (GET /photos/:id.json) with a little less magic but more control than RoR. And I'm not an expert in other framework like Struts2 (still Java), or Django (Python) but I am pretty sure that it is possible too.
What is important :
choose a language (Ruby, Python, Java, PHP, ASP.NET, ...)
choose a framework compatible with RESTfull urls
ensure you can have views in HTML, or JSON, or enter the format you want by adding a suffix or a HTTP header and eventually the appropriate adapter/converter
You could do it by hand but frameworks limits boiler plate code.
The essence of REst was never about how URLs looks like,but how http verbs and headers are used to transfer datas.
This whole "restfull urls" thing is made up by people who dont understand what Rest is. All the Rest spec says is that URLs must be unique.
Now if you really want "restfull" forms,then form should be a resource with an id, like /form/2929929 .Of course it doesnt make sense to do so,since forms are strictly for web users and REst doesnt care about how data is acquiered, only about how it is transfered.
In short,choose whatever URL you want. Some frameworks use new and update for forms. By the way the /questions/ask/submit is totally valid in a Rest context, because what you submit and a question can be 2 totally difference resources.
You need to understand that there is a difference between a RESTfull application and a REST client.
A RESTfull application has pure restfull urls as you described, such as
GET /persons : gets a list of all the persons in database
POST /persons : adds a new person
GET /person/1 : gets a person with id 1
PUT /person/1 : updates person with id 1
DELETE /person/1 : deletes person with id 1
and so on...
Such an application does not have any forms or UI for submitting data. It only accepts data via HTTP requests. To use such an application you can send and receive data using tools like curl or even your browser, which allow you to make HTTP requests.
Now, clearly such an application is not usable from the user point of view. Hence we need to create client applications which consume these restfull applications. These clients are not restfull at all and have urls like:
GET /person/showall : displays a list of all persons
GET /person/create : shows new person form
POST /person/create : submits the data to the restfull application via ajax or simillar technology.
and so on...
These clients can be another HTML application, an android application, an iOS application, etc.
What you are trying to do here is create a single application which has both restful urls for objects as well as forms/pages for data display and input. This is absolutely fine.
Just make sure that you design proper restfull urls for your objects while you can have any url you find suitable for your forms.
In 100% RESTful Web services resources are identified using descriptive URLs, that is URLs composed only of noun phrases.
Generaly speaking, for creating a new resource, you would use PUT, although some frameworks (such as Zend Framework 2, if I remember well), use POST for this purpose. So, for creating a question you could PUT questions, then providing the question identifier in the body of the request, or PUT questions/{identifier}, thus providing the id in the URL.
Contemporary web/cloud applications have moved to what is known as a single page application architecture.
This architecture has a back end REST API (typically JSON based) which is then consumed by either single page applications or native client apps on mobile phones and tablet. The server is then much easier to implement and scale and provides the needed access regardless if its a web client or a native phone/tablet platform.
The client architecture is known as MV* for Model, View and * is anything else the framework provides such as controller logic and persistence.
In my applications I have used a number of MV* frameworks and libraries in anger and investigated many many more. I've had some success with backbone, and my favorite Ember.js, although there are many frameworks and everyone has their favorite for different reasons and that is a whole topic on its own. I will say that depending on the needs of your application different frameworks will be more or less appropriate. I know what matters to my productivity so I have settled on Ember after doing the rounds.
On the backend you have a similar myriad of choices but choose a platform that is known to be mature and stable ans same goes for your data persistence. There are a number of cloud services that give you a REST/JSON api with no coding or deployment concerns now so you can focus more on the client development and less on the server.
It is important to understand that in single page applications the browser url does not need to have a 1 to 1 correspondance with the backend rest api. In fact it would be detrimental to usability taking such a simple minded approach. Of all the client frameworks Ember gets this right as it has a built-in router, and as a result client state is captured in the URL so the page can survive a refresh and can also be bookmarked. You really can keep your client view independent to the backend api endpoints. I design my client URLs around the menu/structure of my forms. In complex apps the URLs nest as far as I need the app to partition and drill down into the details, yet the api endpoints are flat and may span multiple service providers. A view in my client app often assembles data from multiple endpoints and similarly on Accept/Save it pushes to multiple endpoints. It is also possible to implement local persistence so the web client can be used offline and so that temporary or half filled out forms can survive a page refresh.
Another consideration with such an architecture is SEO. With single page applications one needs to be able to provide prerendered pages to web crawlers. Fortunately there are a number of tools which can auto generate the pages for single page applications so that web crawlers can still index your sites content, tools such as pretender.io and many others can solve this for you.
At the end of all this you have a server with a number of REST endpoints and typically a single index.html, app.js app.css and any other assets such as images and fonts.
Typically you need a toolchain for generating these files from your source code which are then either hosted on your domain or on a CDN. I also configure my app and server for CORS so the web client can be hosted on a different domain to the REST back end which also works well in development.
I recommend the broccoli or ember-cli tool chain for assembling all your web client assets and I have also had good experience with Brunch. I've tried most of the tools out there and those are the only ones that get my vote.
For API design I've been actively providing feedback on the latest drafts of JSON API. There is a lot of good work being done there and you can use that as a good starting point.
Usually in production Web Applications I recommend separating how static content is delivered vs how dynamic content is delivered.
Let us hope you are not constrained by SEO and can actually use the wonder of DOM manipulation (ie Client-Side templating)...
I would highly recommend going down the path of learning how to create a SPA (Single Page Application)
However, back to the topic at hand.
Static content (HTML, CSS, Javascript, images) should be delivered thru a different server than your dynamic content (the REST data in json/xml format).
Your HTML should use JQuery/AngularJS/Backbone -- some type of JavaScript framework to actually "render" your HTML on the client-side using JavaScript.
The JavaScript frameworks will also make the proper RESTful calls to POST or PUT a form (which should be a UI representation of some REST path)
Lets say you have a form for a Profile,
GET /profile/{id} would be called to pre-populate a profile FORM
PUT /profile/{id} would be called to update the profile
** JavaScript will pre-populate the FORM by calling one or more RESTful GET methods.
** JavaScript will take entered data from FORM and POST/PUT it to the RESTful server.
The point you should take away from this is:
Let an advanced JavaScript library handle the sending of RESTful requests and "rendering" of the HTML.
HTML is only a template (static content) and can be hosted on a completely different server that is optimized for the job of delivering "static content" :)
Hope that makes sense.
Cheers!
P.S.
Learn about Cross-origin resource sharing (CORS) if you have not already. You will likely need that knowledge to properly host your static content on a different server/domain than your dynamic content.

Using Hypermedia Constraint API to drive UI

I want to use a REST API with hypermedia constraint to drive my UI.
That is, depending on "possible next states" for the resources I fetch, I want to adapt my UI for this.
I'm quite new to UI dev on the web so I wonder if there is any special considerations I need to care about here?
Lets say I have a resource that looks like this:
{
href: "..",
orderDate: date..,
details: {
href : "..",
items: [..],
}
links: [
placeOrder : {
href : "...",
method : "post"
},
cancelOrder : {
href : "...",
method : "delete"
}]
}
Would the above links approach be valid within the context of HATEOAS ?
In a perfect world I guess one should just know about HTTP verbs for actions on the resource but if I want to let the UI know about what can be done to the resource, how do I do this in an idiomatic way?
What I mean is, the same kind of resource can have different "next possible state" depending on current status. And the UI needs to know about this.
Should the UI examine what links are available on the resource or how do I do this?
Yes, exactly. The UI should be coded entirely to the link relations presented to it. If a relation isn't available to follow, it shouldn't be returned in the link collection in the response. That drives not only current state, but also means that the UI isn't burdened with trying to calculate access control rules.
If by idiomatic you mean systematic then the description of the processing rules for the JSON you return need defining, then you communicate your cool new media-type via the Content-Type header.
https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types. Any effort spent describing what methods to use on what URIs of interest should be entirely defined within the scope of the processing rules for a media type (and, in most cases, already defined by existing media types). [Failure here implies that out-of-band information is driving interaction instead of hypertext.]
He's saying to put all your effort into figuring out how to design a data format and its rules such that the system is fully expressive for all its needs, like HTML.
(Or skip this and just use HTML for your API).

RESTful Collection Resources - idiomatic JSON representations and roundtripping

I have a collection resource called Columns. A GET with Accept: application/json can't directly return a collection, so my representation needs to nest it in a property:-
{ "propertyName": [
{ "Id": "Column1", "Description": "Description 1" },
{ "Id": "Column2", "Description": "Description 2" }
]
}
Questions:
what is the best name to use for the identifier propertyName above? should it be:
d (i.e. is d an established convention or is it specific to some particular frameworks (MS WCF and MS ASP.NET AJAX ?)
results (i.e. is results an established convention or is it specific to some particular specifications (MS OData)?)
Columns (i.e. the top level property should have a clear name and it helps to disambiguate my usage of generic application/json as the Media Type)
NB I feel pretty comfortable that there should be something wrapping it, and as pointed out by #tuespetre, XML or any other representation would force you to wrap it to some degree anyway
when PUTting the content back, should the same wrapping in said property be retained [given that it's not actually necessary for security reasons and perhaps conventional JSON usage idioms might be to drop such nesting for PUT and POST given that they're not necessary to guard against scripting attacks] ?
my gut tells me it should be symmetric as for every other representation but there may be prior art for dropping the d/*results** [assuming that's the answer to part 1]*
... Or should a PUT-back (or POST) drop the need for a wrapping property and just go with:-
[
{ "Id": "Column1", "Description": "Description 1" },
{ "Id": "Column2", "Description": "Description 2" }
]
Where would any root-level metadata go if one wished to add that?
How/would a person crafting a POST Just Know that it needs to be symmetric?
EDIT: I'm specifically interested in an answer that with a reasoned rationale that specifically takes into account the impacts on client usage with JSON. For example, HAL takes care to define a binding that makes sense for both target representations.
EDIT 2: Not accepted yet, why? The answers so far don't have citations or anything that makes them stand out over me doing a search and picking something out of the top 20 hits that seem reasonable. Am I just too picky? I guess I am (or more likely I just can't ask questions properly :D). Its a bit mad that a week and 3 days even with an )admittedly measly) bonus on still only gets 123 views (from which 3 answers ain't bad)
Updated Answer
Addressing your questions (as opposed than going off on a bit of a tangent in my original answer :D), here's my opinions:
1) My main opinion on this is that I dislike d. As a client consuming the API I would find it confusing. What does it even stand for anyway? data?
The other options look good. Columns is nice because it mirrors back to the user what they requested.
If you are doing pagination, then another option might be something like page or slice as it makes it clear to the client, that they are not receiving the entire contents of the collection.
{
"offset": 0,
"limit": 100,
"page" : [
...
]
}
2) TBH, I don't think it makes that much difference which way you go for this, however if it was me, I probably wouldn't bother sending back the envelope, as I don't think there is any need (see below) and why make the request structure any more complicated than it needs to be?
I think POSTing back the envelope would be odd. POST should let you add items into the collection, so why would the client need to post the envelope to do this?
PUTing the envelope back could make sense from a RESTful standpoint as it could be seen as updating metadata associated with the collection as a whole. I think it is worth thinking about the sort of meta data you will be exposing in the envelope. All the stuff I think would fit well in this envelope (like pagination, aggregations, search facets and similar meta data) is all read only, so it doesn't make sense for the client to send this back to the server. If you find yourself with a lot of data in the envelope that the client is able to mutate - then it could be a sign to break that data out into a separate resource with the list as a sub collection. Rubbish example:
/animals
{
"farmName": "farm",
"paging": {},
"animals": [
...
]
}
Could be broken up into:
/farm/1
{
"id": 1,
"farmName": "farm"
}
and
/farm/1/animals
{
"paging": {},
"animals": [
...
]
}
Note: Even with this split, you could still return both combined as a single response using something like Facebook's or LinkedIn's field expansion syntax. E.g. http://example.com/api/farm/1?field=animals.offset(0).limit(10)
In response, to your question about how the client should know what the JSON payload they are POSTing and PUTing should look like - this should be reflected in your API documentation. I'm not sure if there is a better tool for this, but Swagger provides a spec that allows you to document what your request bodies should look like using JSON Schema - check out this page for how to define your schemas and this page for how to reference them as a parameter of type body. Unfortunately, Swagger doesn't visualise the request bodies in it's fancy web UI yet, but it's is open source, so you could always add something to do this.
Original Answer
Check out William's comment in the discussion thread on that page - he suggests a way to avoid the exploit altogether which means you can safely use a JSON array at the root of your response and then you need not worry about either of you questions.
The exploit you link to relies on your API using a Cookie to authenticate a user's session - just use a query string parameter instead and you remove the exploit. It's probably worth doing this anyway since using Cookies for authentication on an API isn't very RESTful - some of your clients may not be web browsers and may not want to deal with cookies.
Why Does this fix work?
The exploit is a form of CSRF attack which relies on the attacker being able to add a script tag on his/her own page to a sensitive resource on your API.
<script src="http://mysite.com/api/columns"></script>
The victims web browser will send all Cookies stored under mysite.com to your server and to your servers this will look like a legitimate request - you will check the session_id cookie (or whatever your server-side framework calls the cookie) and see the user is authenticated. The request will look like this:
GET http://mysite.com/api/columns
Cookie: session_id=123456789;
If you change your API you ignore Cookies and use a session_id query string parameter instead, the attacker will have no way of tricking the victims web browser into sending the session_id to your API.
A valid request will now look like this:
GET http://mysite.com/api/columns?session_id=123456789
If using a JavaScript client to make the above request, you could get the session_id from a cookie. An attacker using JavaScript from another domain will not be able to do this, as you cannot get cookies for other domains (see here).
Now we have fixed the issue and are ignoring session_id cookies, the script tag on the attackers website will still send a similar request with a GET line like this:
GET http://mysite.com/api/columns
But your server will respond with a 403 Forbidden since the GET is missing the required session_id query string parameter.
What if I'm not authenticating users for this API?
If you are not authenticating users, then your data cannot be sensitive and anyone can call the URI. CSRF should be a non-issue since with no authentication, even if you prevent CSRF attacks, an attacker could just call your API server side to get your data and use it in anyway he/she wants.
I would go for 'd' because it clearly separates the 'envelope' of your resource from its content. This would also make it easier for consumers to parse your responses, as opposed to 'guessing' the name of the wrapping property of a given resource before being able to access what it holds.
I think you're talking about two different things:
POST request should be sent in application/x-www-form-urlencoded. Your response should basically mirror a GET if you choose to include a representation of the newly created resource in your reply. (not mandatory in HTTP).
PUTs should definitely be symmetric to GETs. The purpose of a PUT request is to replace an existing resource representation with another. It just makes sense to have both requests share the same conventions, doesn't it?
Go with 'Columns' because it is semantically meaningful. It helps to think of how JSON and XML could mirror each other.
If you would PUT the collection back, you might as well use the same media type (syntax, format, what you will call it.)