Projection/ Partial RESTful HTTP GET requests

667 megtekintés
Ugrás az első olvasatlan üzenetre

Constantin Gerstberger

olvasatlan,
2014. ápr. 4. 4:54:292014. 04. 04.
– api-...@googlegroups.com
Hello everyone,

i wonder whether or not it is possible to do partial read requests with HTTP in a REST-compliant fashion (something like PATCH for read requests).

Let's assume, we have a resource identifier like "/products/1" which maps to a respective entity having a representation like this (i purposely excluded hypermedia elements for simplification reasons):

{
id: 1,
name: xxx,
description: yyy,
category: zzz,
price: 42,
...
}

Protocols like OData allow to request a projection of this entity, for example: /Product(1)?$select=id, name (which would only return the id and name attribute).

According to my understanding, this is not RESTful as the client has out of band information about the resource:
  • Its exact structure
  • the fact that $select can be used (based on the assumption that client only received the information that the product can be received via "/products/1" as the projection is arbitrary)

- Does this still hold in case you add a custom media type to the request (e.g. application/vnd.myapp+xml)?
- Would creating separate resource ids be a correct solution?


Thanks in advance.




Jørn Wildt

olvasatlan,
2014. ápr. 4. 6:50:152014. 04. 04.
– api-...@googlegroups.com
You can put the information more in-band by tying the projection details to the link relation that leads to the resource.

Assume you use a media type with link templates (in this case Mason) - then you could do something like below on the resource containing the link:

{
  "@link-templates":
  {
    "http://api.acme.com/rel-types#related-product":
    {
      template: "http://api.acme.com/products/1?$select={projection},
      title: "Link template for related product details",
      parameters:
      [
        {
          name: "projection",
          description: "Projection expression. Comma separated list of JSON path elements"
        }
      ]
    }
  }
  ... Plus other properties in the "previous" resource containing a link to your /products/1 resource ...
}

I guess you could do similarly with a "self" link template on the /products/1 resource.

You could also simply document the availability of $select in the link relation docs.

/Jørn



--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft.
For more options, visit https://groups.google.com/d/optout.

Constantin Gerstberger

olvasatlan,
2014. ápr. 4. 12:06:252014. 04. 04.
– api-...@googlegroups.com
Thanks, that example made things much clearer. However, i'm still not sure how exactly the client may find out about which columns are valid projection elements (except when the server explicitly states them).

May a client deduce them from the data format (in case it says that a product representation always has e.g. an id and a title) or could the server have added a semantic link (e.g. to schema.org/product)?

Both somehow seem to conflict with the idea of having multiple representations.

/Constantin

Pete Johanson

olvasatlan,
2014. ápr. 4. 12:19:382014. 04. 04.
– api-craft@googlegroups com

Is I a requirement that clients have full control of the fields they do or don't want returned?

If there are simply a few well known sets of field combinations, why not allow clients in their request to specify both the requested generic media type plus a specific profile for what fields they want ( http://www.mnot.net/blog/2012/04/17/profiles)

So you could have the default representation for the resource, or request the 'limited' profile in the Accept header and get those fields in the response.

Doing so assists with better cache-ability, and preserves this as a single resource, but with different representations.

Thoughts?
-pete

Constantin Gerstberger

olvasatlan,
2014. ápr. 7. 9:20:212014. 04. 07.
– api-...@googlegroups.com
"Full control at compile time" is probably the best description i can come up with right now.

The scenario i'm working with is having multiple client applications which some being interested in different (but static per application) projections of a resource and additional client applications potentially being added over time (as part of an architecture i work on for my master thesis).
Partly, projections might as well be caused by security considerations (though this should be performed by the server implicitly, i think). The motivation here would be to avoid sending data being redundant from the client's perspective (maybe that's a bad reason after all ...).

The link header definitely seems useful for that purpose (Too bad that it cannot be used as a request header as well). However, one down side of using profiles could be that you now have to manage profiles (and potentially their versions) on top of resources.

Another approach i thought of was contextualizing the resource identifier, e.g. <useCaseName>/path/to/resource. But i guess the context is too abstract to get a solution the works in any case. 

Pete Johanson

olvasatlan,
2014. ápr. 7. 9:30:122014. 04. 07.
– api-craft@googlegroups com

You can use the profile qualifier in the Accept header of your request, FYI.

-pete

Válasz mindenkinek
Válasz a szerzőnek
Továbbítás
0 új üzenet