Avoiding ambiguity in API signatures

60 ملاحظات
پہلے نہ پڑھے ہوئے پیغام پر جائیں

Andrew B

نہ پڑھا ہوا،
17 جولائی، 2016، 7:35:49 PM17/7/16
بنام API Craft
I have a question about the abilities of various back end frameworks to resolve potentially ambiguous incoming API calls....

So far we've tried to avoid ambiguity in our API urls, to make it as easy as possible for developers to produce them.

For example, we might have two APIs like this, one to view an existing product, and one to get a list of retired products:
  • GET /products/{ID}
  • GET /products/retired
Product ID is always an integer, so there's no ambiguity here ("retired" can never be used as an ID).

Spring MVC for example can deal with this, because it knows that ID must be a number (hence can't start with "r") by introspecting the arguments to the endpoints, e.g.: 

@RequestMapping(value = "/products/{ID}")
public String viewProduct(@PathVariable("ID") Long productID) {


 
However we're concerned there may be other back end frameworks that can't easily deal with this kind of ambiguity.

So instead we've opted for the following, which is more verbose and feels slightly yuck:
  • GET /products/byID/{ID}
  • GET /products/retired
Does anyone have any knowledge or experience as to whether this is even necessary? We don't care too much about aged or arcane frameworks, but are there common garden frameworks that can't deal with these kind of semi-ambiguous situations? Or are we making our API signatures unnecessarily verbose for no strong reason?

J Fernandes

نہ پڑھا ہوا،
18 جولائی، 2016، 3:42:50 AM18/7/16
بنام api-...@googlegroups.com
Hi,

Have you considered something like:
  /products/{id}
  /retired/products

Hope that helps,

Joao
--
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 https://groups.google.com/group/api-craft.
For more options, visit https://groups.google.com/d/optout.

Ivan Novakov

نہ پڑھا ہوا،
18 جولائی، 2016، 4:32:39 AM18/7/16
بنام api-...@googlegroups.com
Hi,

the /products/byID/{ID} option is not considered RESTful and might be confusing.
If you need to filter the /products collection by some value, you can use this generic approach:

/products?<filter>=<vaue>

In your case:

/products?retired=1

Regards,
Ivan

Srinivas Ivaturi

نہ پڑھا ہوا،
18 جولائی، 2016، 8:57:15 AM18/7/16
بنام api-...@googlegroups.com
I second Ivan's approach. Query Parameters help in this case to filter down the collection of data you want to return. 
Thanks
Srinivas Ivaturi.
~ A Directionless Driven Life!

Simon Renoult

نہ پڑھا ہوا،
18 جولائی، 2016، 10:52:46 AM18/7/16
بنام API Craft
I agree this design is not optimal. That's what I would do:

GET /products?state=retired # if "state" makes sense with your product lifecycle

OR
 
GET /products?retired=true

Andrew B

نہ پڑھا ہوا،
18 جولائی، 2016، 5:24:20 PM18/7/16
بنام API Craft
Thanks for your input and others on using query parameters. I'm not sure why our current approach is not considered restful.

We're committed to using distinct URIs, not query parameters, since each API may be produced by a different back end. Retired products may be pulled out of (say) glacier. Active products from a transactional database. So we're ruling out the query parameters route.

Chris Mullins

نہ پڑھا ہوا،
20 جولائی، 2016، 10:07:38 PM20/7/16
بنام API Craft
I get that your using different data sources for active/retired products. Hopefully *not* glacier, unless you like to measure API latency in days, but I get that it's a different system (DynamoDB, S3, SimpleDB [although I think that's gone by now], Mongo, or whatever).  

I don't understand why having distinct URI's makes this any easier (or harder). The front door has to look at something - be it a query parameter or a URI Segment - and make routing and execution decisions. The only thing I can think of is that you're network routing via some reverse proxy based on the path, and therefore hitting a physically different server. This seems very fragile, and probably longer term more work. 


Cheers,
Chris

Andrew B

نہ پڑھا ہوا،
20 جولائی، 2016، 10:53:08 PM20/7/16
بنام API Craft
Yeah, this is really a question about the nitty gritty of different API front end technologies. Since we mainly use Java + Spring we don't know everything that's out there.

For example, anecdotally, some platforms can't support hosting these two endpoints at the same time:
  • GET /products/{ID}
  • GET /products/retired
Because they use naive decoders/routers and they get confused when something like this comes in:

GET /products/retired

They look at this and can't work out if that's a call to the first API with an ID of "retired" or a call to the second API.

As I said, Spring seems to have no problems in this area, because it knows that ID is a number, hence it knows that this cannot be a call to the first API, so there is no ambiguity.

I'd just like to know if this is urban myth or something we do need to consider or if all platforms can handle this with their eyes closed.

On one hand we don't want to be defining APIs that can't be implemented because of the above problem on some common platform like .net, node.js, php, rails, etc. etc.. On the other we obviously want them to be as short as they can be.
سبھی کو جواب دیں
مصنف کو جواب دیں
فارورڈ کریں
0 نئے پیغامات