Summary of OData standard for a minimal, read-only implementation - json

The OData specification is long. Even the "OData Core" document is pretty long.
So, how about a condensed summary of what a read-only OData publisher needs to implement at a minimum?

I'll start. An OData service provides an HTTP endpoint that:
MUST understand "Accept" headers
MUST support Content-Type header, and MUST support ATOM format (optionally JSON)
MAY return a service document (list of collections) to GET / (10.1.1)
If ATOM (AtomPub?) format, the hierarchy is service/workspace/collection/title
MUST return descriptions of collections to requests like GET /Customers (10.2)
If ATOM, the hierarchy is feed/entry/content
MUST return descriptions of individual entities to requests like GET /Customers(3) (10.2.1)
MAY return individual properties of individual entities for requests like GET /Customers(3)/Name (10.2.2)
MUST make available a CSDL schema description wrapped in an EDMX document (10.1.2)
This SHOULD be available at /$metadata
MAY support any of these queries (10.2.3)
Filters (limit rows returned): Products?$filter=Price lt 10.00
Select (limit fields returned): Products?$select=Rating,ReleaseDate
Order-by: Products?$orderby=ReleaseDate asc, Rating desc
Top, skip: Products?$top=5&$skip=2
InlineCount (include an entity count): Products?$inlinecount=allpages
MUST (?) provide a list of relationships for an entity (10.2.4): Products(0)/$links/Orders
MUST provide an entity count (10.2.5): Products/$count
MAY support other formats with $format specifier (10.2.3.7)
When an ATOM feed is returned (such as for a collection), it needs to conform to some OData conventions: http://www.odata.org/documentation/odata-v3-documentation/atom-format/ For example:
Types used are "edm:String" etc.
link elements are used generously
content elements either contain content inline (eg, text data), or link to it (eg, images, binary files) with src= attribute.
When a JSON feed is returned, it similarly follows certain rules:
http://www.odata.org/documentation/odata-v3-documentation/json-verbose-format/
URLs are encouraged to follow this scheme:
http://www.odata.org/documentation/odata-v3-documentation/url-conventions/

Related

Should I be using JSON or XML when the order of the properties, of the server-returned object, matters?

Client uses ReactJS and server is using Node, Express and MySQL for the db. I'm making a website that allows users to post news articles, e.g. long bodies of text with images inserted at random points inside them. Think of a website like Medium that allows users to write blog posts and insert images at any point.
My issue here lies with how I am to store the information for each article. Originally, I was going to use XML - use and tags and represent each article as an XML document. This way, when the server parses the XML document after pulling it from the DB, the order of the elements is preserved.
For example:
<<text> /* long body of text (e.g. about 300 - 500 words?) */ </text>
<img> First image path goes here </img>
<text> /* Another body of text! */ </text>
<img> Some cool graph that's relevant for the article </img>
When my server tries to parse this XML document, the order is very important. The contents of the first text tag (line 1 in the code sample above) must be parsed first. Then below that should be the first image (line 2). Once the full XML document is parsed, it should be sent to the client, where React will iterate through the returned object and, create a paragraph or image ReactElement for each object.
I use JSON for most things to represent the objects that client and server exchange. But, I am quite aware that within JSON objects, the order of the keys {key: value}, is not preserved. Therefore, it would be possible that (referring to my silly code snippet above), line 2 could be added to my VirtualDOM before line 1, making the outputted order incorrect.
Therefore, should I be using JSON or XML as 1) the format of the object that the server returns and 2) the representation of each article.
Both XML and JSON have the ability to represent data in a way that preserves order. The nearest JSON equivalent to your XML might be:
[
{"text":"long body of text (e.g. about 300 - 500 words?)"},
{"img":"First image path goes here"},
{"text":"Another body of text!"},
{"img":"Some cool graph that's relevant for the article"}
]
Because order matters, you have to use an array here.
You could argue that this structure looks pretty strange, and you would be right. JSON was never designed for representing document structures. I would strongly question the wisdom of using JSON to represent free-format articles in the way you are proposing. There are some things JSON does better than XML, and there are other things XML does better than JSON, and your application is firmly in the second category.
MySQL's JSON data type does not preserve the order however you can store it as a string which will save idempotency. But you lose the ability to use the MySQL JSON functions, which you might be able to live with if your processing is mainly in your application.

http rest: Disadvantages of using json in query string?

I want to use query string as json, for example: /api/uri?{"key":"value"}, instead of /api/uri?key=value. Advantages, from my point of view, are:
json keep types of parameters, such are booleans, ints, floats and strings. Standard query string treats all parameters as strings.
json has less symbols for deep nested structures, For example, ?{"a":{"b":{"c":[1,2,3]}}} vs ?a[b][c][]=1&a[b][c][]=2&a[b][c][]=3
Easier to build on client side
What disadvantages could be in that case of json usage?
It looks good if it's
/api/uri?{"key":"value"}
as stated in your example, but since it's part of the URL then it gets encoded to:
/api/uri?%3F%7B%22key%22%3A%22value%22%7D
or something similar which makes /api/uri?key=value simpler than the encoded one; in this case both for debugging outbound calls (ie you want to check the actual request via wireshark etc). Also notice that it takes up more characters when encoded to valid url (see browser limitation).
For the case of 'lesser symbols for nested structures', It might be more appropriate to create a new resource for your sub resource where you will handle the filtering through your query parameters;
api/a?{"b":1,}
to
api/b?bfield1=1
api/a?aBfield1=1 // or something similar
Lastly for the 'easier to build in client side', i think it depends on what you use to create your client, usually query params are represented as maps so it is still simple.
Also if you need a collection for a single param then:
/uri/resource?param1=value1,value2,value3

rest api response format

Should I treat all api response as "resource" and return a JSON object or simple array would be appropriate as well ?
for instance are all of the below responses valid?
GET /rest/someresource should return collection of ids
[{id:1},{id:2}]
{{id:1},{id:2}}
[1,2]
GET /rest/someresource?id>0 search for ids bigger than zero and return collection of ids
[{id:1},{id:2}]
{{id:1},{id:2}}
[1,2]
Collection Resources
It is acceptable to return an array of resources - either a list of ids, or object structures - such a thing is commonly known as a 'collection' resource.
See http://51elliot.blogspot.com.au/2014/06/rest-api-best-practices-4-collections.html for an examination of resources and collections.
While not required by REST, it's common to use a plural noun to refer to a collection resource - e.g.
/rest/someresources
REST also requires the use of defined media types, and there are a couple available to assist with collections, e.g.:
Collection+json
Provides a structure with meta data around a list of items wherein you define the structure of each item as your resource
HAL
provides a structure with embedded collections and embedded resources
And many more
All provide a defined structure for including hypermedia links for your resource, or each resource in your collection - and if you are doing REST this is one of the things that the spec says you MUST do (even though many people don't).
Your Proposed Json Structures
Some more specific comments on your proposed json structures:
Option 2 is not valid json. Consider:
{{id:1},{id:2}}
A json object must have a name:value pair, e.g.
{somename:{id:1},someothername:{id:2}}
would be valid - but not very useful!
Also - strictly for json, the name should be enclosed in quotes. the value may be enclosed in quotes if it is a string.
So if you don't want to use a commonly used media type as referenced above, your options are 1 or 3. which should be:
[{"id":1},{"id":2}]
[1, 2]
Both are valid, however option 1 will give you more flexibility to add more properties to each element of the array if you decide in the future you would like to return more than an id. e.g. at some point in the future you might decide to return:
[{"id":1,"name":"fred"},{"id":2,"name":"wilma"}]
Option 3 will only ever be able to return a list of ids.
So personally I would go with option 1.
Depends on how RESTful you're aiming to be.
In addition to what #Chris Simon said, I'll add that if the server would only return IDs at GET /rest/someresource, the client would have to repeatedly call something like GET /rest/someresource/{id} in order to obtain data (it can display on the UI), right? This in turn would just increase the load on the server. If the id would be enough, you can probably get away with the proposed solution.
Also, once you decide you'd better be consistent.
Given that the 2nd option is not even valid, and the last is pretty limiting, I'd also go for the first option, JSON.
Just to make it clear we are talking about different representations of the same resource here:
By GET /rest/someresource both [{id:1},{id:2}] and [1,2] are valid responses, but you should make clear which one you want to see, e.g. with the prefer header. So by Prefer: return=minimal you would return [1,2] and if the header is not present, then [{id:1},{id:2}]. Just make sure that the prefer header is registered by the vary header, or you will have caching troubles.
By GET /rest/someresource?id>0 you filter your collection. So either the /rest/someresource?id>0 URI identifies a different filtered collection resource or it identifies the same collection resource, but with the filter query string your client indicates that it is waiting for a filtered representation of the resource and not the full representation. You can use the same by the minimal representation if you don't want to use the prefer header: GET /rest/someresource?return=minimal.
Note that if you want your client to query again, then you should send them hyperlinks in your response. The REST client must get the URIs (or URI templates) from these hyperlinks and it should not start to build URIs on its own.

box .Net v2 API how to fetch all fields?

The Box v2 REST API appears to contain methods that return "full objects". That is, they return all the fields and properties of the object requested with one "simple" call.
When trying the official .Net SDK, it appears that if you don't specify fields by name in the "FoldersManager" or "FilesManager" (for example), you get minimal details of the objects returned.
Is there a way to make the request return all fields/properties? I realize maybe ItemsCollection is one you'd want to retrieve specifically, but the rest should really be included in one call (like the REST capability).
Thanks for any ideas!
-AJ
If no fields are specified in the request, the default fields are returned in the response (ie. what the API decides is the most commonly used fields). If a field is specified the API returns all required fields along with the specified fields (usually type, id, and etag).
There is currently no simple flag that will return all fields as this would likely be abused out of convenience. The only way to return all fields is to manually specify all of the fields you are looking for. If using any of the official SDKs, these fields names can usually be found in the object models
HTH

JSON output to the browser -> providing an order

So I've read that you cannot expect a default order when requesting json. I've seen this in action making a call to a little api that I built, that will return a jumbled, random order of elements each time I make a different call.
How does a site like ticketfly's api ( call it here http://www.ticketfly.com/api/events/upcoming.json?venueId=57 ) always ensure that the json returned is in a specific order?
The event ids always first, etc.
Thanks for shedding some light on the situation.
If you are in control of the endpoint API then you can hardcode the order in which you render the properties. Though I have to ask why exactly do you need the JSON properties in a particular order? You will finally be accessing the properties via there property names so the order in which they appear in the JSON should not ideally matter.
EDIT : Since your bosses insist on this (what can one say now?):
You can try and see if any of the following suits your needs:
Try hardcoding the display order in the view's representation. This means you will need to echo/print each property name explicitly in the view script. In PHP it could be something like echo $variable_representing_json["id"]; and so forth. Note that with this approach you needn't change the original JSON representation.
If you want the original JSON representation to be changed then depending on how you are doing the process it varies in difficulty:
If it's string concatenation that you are using to represent the json then hard-code the order in which the json properties get concatenated in the string.
In some languages the display order of properties is actually a representation of the order in which the properties were defined. In simple words if $var is an empty json representation then you should define $var["id"] = {some_val} first to display it first.
If you are using a framework for processing the JSON data it may have its own quirks irrespective of how you define your representation. In such cases you will have to try and see if you can work around the issue or if it gives any helper methods.