RESTful Collection Resources - JSON Idioms and Round Visits

I have a collection resource called Columns. A GET with Accept: application/json cannot directly return a collection , so my view needs to attach it to a property: -

 { "propertyName": [ { "Id": "Column1", "Description": "Description 1" }, { "Id": "Column2", "Description": "Description 2" } ] } 

Questions:

  • Which name is best used for the propertyName identifier above? it should be:

    • d (i.e. d is an established agreement or is it specific to some specific frameworks ( MS WCF and MS ASP.NET AJAX ?)
    • results (i.e., results are an established agreement or is it specific to some specific specifications ( MS OData )?)
    • Columns (i.e. the top-level property should have a clear name, which helps eliminate my use of common application/json as the media type)

    NB I feel pretty comfortable that there must be something to wrap it, and as pointed out by @tuespetre, XML or any other representation will force you to wrap it anyway.

  • when accessing the contents back, if the same packaging in the specified property is saved [if it is really not necessary for security reasons, and perhaps the usual idioms of using JSON may discard such nesting for PUT and POST, given that they "no need to protect against script attacks"?

    my gut tells me that it should be symmetrical, as for any other representation, but may be aware of the art of removing the results d / * ** [provided that the answer to part 1] *

    ... Or you want the PUT-back (or POST) to lose the need for the wrapping property and just go with: -

      [
            {"Id": "Column1", "Description": "Description 1"},
            {"Id": "Column2", "Description": "Description 2"}
      ]
    
    • If any metadata at the root level would go away if you wanted to add this?
    • How / does the person who created the POST just need to know that it needs to be symmetrical?

EDIT: I am particularly interested in the answer with reasonable justification, which specifically takes into account the effect on the use of the client with JSON. For example, HAL allows you to define a binding that makes sense for both representations of goals.

EDIT 2: Not accepted, why? There are no quotes or anything in the answers so far that makes them stand out because of me, doing a search and choosing something from the top 20 hits that seem reasonable. Am I just too picky? Probably, I (or, most likely, just can not ask the right questions: D). Its a little crazy that a week and 3 days even c) admittedly insignificant) the bonus on still only gets 123 views (of which 3 answers are not bad)

+7
source share
3 answers

Updated Answer

Turning to your questions (as opposed to moving a little tangentially in my original answer: D), here are my opinions:

1) My main opinion on this is that I do not like d . As a client consuming an API, I find it confusing. What does it mean? data?

Other options look good. Columns nice because it is calling the user with a request.

If you are paginating, then the other option may be something like page or slice , because it makes it clear to the client that they do not receive the entire contents of the collection.

 { "offset": 0, "limit": 100, "page" : [ ... ] } 

2) TBH, I don’t think that it greatly affects how you do it, however, if it were me, I probably would not send the envelope back, since I don’t think there are any ( see below) and why make the query structure more complex than it should be?

I think posting back the envelope would be strange. POST should allow you to add items to the collection, so why would the client need to place an envelope for this?

Resetting the envelope may make sense from a RESTful point of view, as it can be seen as updating the metadata associated with the collection as a whole. I think it's worth considering which metadata you will strip in the envelope. All material that, it seems to me, fits well into this envelope (for example, pagination, clusters, fax searches and similar metadata) is read-only, so the client has nothing to send back to the server. If you find that there is a lot of data in the envelope that the client can mutate, then it may be familiar to break this data into a separate resource with a list as a subcategory. Example garbage:

/animals

 { "farmName": "farm", "paging": {}, "animals": [ ... ] } 

It can be divided into:

/farm/1

 { "id": 1, "farmName": "farm" } 

and

/farm/1/animals

 { "paging": {}, "animals": [ ... ] } 

Note. Even with this section, you can still return both combined as a single response using something like Facebook or the LinkedIn field extension syntax . For example. http://example.com/api/farm/1?field=animals.offset(0).limit(10)

In answer to your question about how the client should know what JSON payload they represent POSTING and PUTing, it should look like this: this should be reflected in the API documentation. I'm not sure if there is a better tool for this, but Swagger provides a specification that allows you to document which request bodies should look like this: JSON schema - check this page to determine your schemas and this page to reference them as a parameter of type body . Unfortunately, Swagger does not yet visualize the request organs in this fraudulent web interface, but it is open source, so you can always add something for this.

Original answer

Mark William’s comment on the discussion topic on this page - it offers a way to avoid the exploit altogether, which means that you can safely use the JSON array at the root of your answer, and then you don’t have to worry about any of the questions.

The exploit you use relies on your API using cookies to authenticate the user session - instead, just use the query string parameter and you will remove the exploit. This is probably worth doing, because using cookies for authentication in the API is not very RESTful - some of your clients may not be web browsers and may not want to deal with cookies.

Why does this fix work?

An exploit is a form of CSRF attack that assumes that an attacker can add a script tag to his own page on a sensitive resource of your API.

 <script src="http://mysite.com/api/columns"></script> 

The victim’s web browser will send all cookies stored in mysite.com to your server and to your servers, it will look like a legitimate request - you will check the session_id cookie (or whatever your server infrastructure calls the cookie) and see that 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 the session_id string parameter instead, the attacker will not be able to trick the victims web browser by sending session_id to your API.

Now the actual request will look like this:

 GET http://mysite.com/api/columns?session_id=123456789 

If you use the JavaScript client to execute the above request, you can get session_id from the cookie. An attacker using JavaScript from another domain will not be able to do this, since you cannot receive cookies for other domains ( see here ).

Now we fixed the problem and ignore the session_id cookie, the script tag on the attackers website will still send a similar request using the GET string as follows:

 GET http://mysite.com/api/columns 

But your server will respond with 403 Forbidden , as the required parameter for the session_id string is missing from GET.

What if I do not authenticate users for this API?

If you do not authenticate users, your data may not be sensitive, and anyone can call a URI. CSRF should be no problem, because without authentication, even if you prevent CSRF attacks, an attacker could just call your side of the API server to get your data and use it anyway.

+3
source
  • I would choose 'd' because it clearly separates the "envelope" of your resource from its contents. It would also make it easier for consumers to analyze your answers, rather than “guessing” the packaging property name of a given resource before they can access what it holds.

  • I think you are talking about two different things:

    • The POST request should be sent to application/x-www-form-urlencoded . Your answer should mainly reflect GET if you decide to include a view of the newly created resource in your answer. (optional in HTTP).
    • PUTs should definitely be symmetric with GET. The purpose of a PUT request is to replace an existing resource representation with another. It just makes sense that both requests have the same conventions, right?
+2
source
  • Go to "Columns" because it is semantically significant. It helps to think about how JSON and XML can reflect each other.

  • If you put the collection back, you can also use the same type of media (syntax, format, whatever you name it.)

+1
source

All Articles