Re: Web API Design 2nd Edition (APIGEE)

Showing 21-60 of 60 messages
Re: Web API Design 2nd Edition (APIGEE) Kristof Kotai 9/29/12 11:57 AM
Hi everyone,
just wanted to give my feedback on this book: http://offers.apigee.com/api-design-ebook-rr (since the author mentioned that we can post feedback here, I'll do so...). I actually have more questions, but I'll just start with one so that we can focus on them one-by-one...

So the first thing I wanted to ask is about the use of verbs and nouns in the URIs. The ebook seems to advise developers to make a clear distinction between calls that are named using verbs (calls that don't work on resources, which rather make some sort of calculation / conversion / translation that don't involve resources being returned) and resources, that map to something in the database for example. Using an example from the ebook:

GET /convert?from=EUR&to=CNY&amount=100

Sure, I understand that in this case this is the best way to name the URI, but in general? Why would it be. I mean, verbs are the only way to describe actions. And sometimes you have to make actions (other than CRUD) on resources... Obviously you can not invent new HTTP methods for that purpose, so you have to add verbs somehow. The ebook refers a lot to Foursquare's API (and it approves of that as well), but looking at their API, that quite contradicts what the author says. For example:


"addcomment" is a verb, and no it is not a clearly separated call, the resource name is still there as a prefix. So would the following be the right solution then?


I think Foursquare's approach is spot on, but then why does the author say the complete opposite? That if you use verbs, don't mix it with existing resource names, and you should somehow indicate in the API docs that these calls are separate from the rest of the resource-based calls.

Thanks, Kristof
Re: [api-craft] Web API Design 2nd Edition (APIGEE) mikeschinkel 9/29/12 2:20 PM
Apigee is not unique in its advocacy of nouns instead of verbs, it's a REST best practice and it has been written about ad-nauseum so I would try to duplicate it here, just google "REST nouns not verbs" to find some of the better writings on the subject.

Regarding Foursquare's API just because it's considered good in general doesn't mean it's perfect.  That's like expecting a person to be 100% good or 100% evil. :)

Instead of "Convert", why not "Conversion?" You really don't care how it's converted do you (the verb?) You just care about the resultant conversion info (the noun.)  So I'm using a cleaner URL syntax because that's my preference to demonstrate:

GET /conversion/EUR/CNY/100

Hope this helps.

-Mike

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 

Re: [api-craft] Web API Design 2nd Edition (APIGEE) Kristof Kotai 9/30/12 12:45 AM
Mike,
the reason why I brought this topic up, is that according to the book choosing between nouns and verbs in API calls creates certain assumptions of the underlying model on the API's side. If you use a noun, then that should map to something in a database. Whereas non-resource-y things (that doesn't include a database read or write) should be separated from the rest of the calls.

In your example, you just used the noun form of the verb, but my problem wasn't about linguistics. Because that way you are implying that you have a some kind of DB representation of the "conversion" resource. But actually that is not a resource...

If you read the relevant section in the ebook again, I think you will see what my real question was.

thanks, Kristof
Re: [api-craft] Web API Design 2nd Edition (APIGEE) mikeschinkel 9/30/12 2:16 AM
On Sep 30, 2012, at 3:45 AM, Kristof Kotai <kotai....@gmail.com> wrote:
If you read the relevant section in the ebook again, I think you will see what my real question was.

Okay, I just read page 19 and see what you were referring to, I guess I misread your post. Sorry. 

That said, I can't say that the recommendations on that page make any sense to me either.  I think it's bad form to build an API based on how it's implemented in the back end; the API should be designed from the perspective of the user of the API. I also don't think there are many (any?) cases where verbs sense to identify resources.

-Mike

Re: [api-craft] Web API Design 2nd Edition (APIGEE) Steve Klabnik 9/30/12 7:11 AM
> That said, I can't say that the recommendations on that page make any sense
> to me either.  I think it's bad form to build an API based on how it's
> implemented in the back end; the API should be designed from the perspective
> of the user of the API.

Yep, :+1: from me, here, too. This is the largest problem with
building apps in Rails; ActiveRecord + "REST"ful routes encourages a
1-1 mapping between tables and resources.

>  I also don't think there are many (any?) cases where
> verbs sense to identify resources.

I could theoretically see some sort of resource that you only POST-ed
to to process something being a verb, but that wouldn't be ideal, it'd
just be acceptable.
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Glenn Block 9/30/12 7:41 AM
Weighing in...

Who says the noun has map 1 to 1 to the database? I don't think that is true at all. A resource is a resource is a resource, the only constraints are how it is accessed (HTTP Methods, security) and how it behaves (ie catchable, idempotent)

You can absolutely have resources which are not backed by any database or even any persistence mechanism. For example you can have a Calculator resource that is completely stateless and idempotent. You do a GET to it passing some information like this http://calculation.com/calculator/add/2+3 (no this does not exist) and it returns the result. The result never changes so it is cachable.

The main thing about using nouns as resources is it naturally fits with the uniform interface. I can check up on a thing (GET), I can add a thing (POST), I can replace a thing (PUT) and I can remove it (DELETE). 'Thing' here means noun. Now not everything supports all methods as in the example I just posted, that resource only supports GET. But that is also fine as I am not violating any thing from an HTTP perspective. 

In terms of 'actions' behind each action there is a noun waiting to be discovered. The example I use (overuse) is contact management. Let's say I have a contact resource. Now I want to support the ability for contacts to connect, so I can say 'Glenn connects to Steve'. Connect is a verb, but I can flip things around and say contacts have connections, and there you go, my connections resource is born. I can now post 'Steve' to '/contacts/glenn/connections'. The uniform interface comes in nicely here because I can get connections, add connections, remove connections. 

Take another example, order management. Orders need to be fulfilled. Uh oh, that means I have a fulfill verb. But then I can say orders have a fulfillment resource, which I post to in order for the order to get fulfilled.

My experience is you can pretty much model ANY action resourcefully in this way. 
To unsubscribe from this group, send email to api-craft+unsubscribe@googlegroups.com.

Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Glenn Block 9/30/12 7:44 AM
'It's a REST best practice'. 

On my soapbox....

It may be that people building RESTful systems do this, but please everyone remember that REST itself has nothing to say about whether your uris are verbs or nouns.



On Saturday, September 29, 2012, Mike Schinkel wrote:
Apigee is not unique in its advocacy of nouns instead of verbs, it's a REST best practice and it has been written about ad-nauseum so I would try to duplicate it here, just google "REST nouns not verbs" to find some of the better writings on the subject.

Regarding Foursquare's API just because it's considered good in general doesn't mean it's perfect.  That's like expecting a person to be 100% good or 100% evil. :)

Instead of "Convert", why not "Conversion?" You really don't care how it's converted do you (the verb?) You just care about the resultant conversion info (the noun.)  So I'm using a cleaner URL syntax because that's my preference to demonstrate:

GET /conversion/EUR/CNY/100

Hope this helps.

-Mike

On Sep 29, 2012, at 2:57 PM, Kristof Kotai <kotai.kristof@gmail.com> wrote:

Hi everyone,
just wanted to give my feedback on this book: http://offers.apigee.com/api-design-ebook-rr (since the author mentioned that we can post feedback here, I'll do so...). I actually have more questions, but I'll just start with one so that we can focus on them one-by-one...

So the first thing I wanted to ask is about the use of verbs and nouns in the URIs. The ebook seems to advise developers to make a clear distinction between calls that are named using verbs (calls that don't work on resources, which rather make some sort of calculation / conversion / translation that don't involve resources being returned) and resources, that map to something in the database for example. Using an example from the ebook:

GET /convert?from=EUR&to=CNY&amount=100

Sure, I understand that in this case this is the best way to name the URI, but in general? Why would it be. I mean, verbs are the only way to describe actions. And sometimes you have to make actions (other than CRUD) on resources... Obviously you can not invent new HTTP methods for that purpose, so you have to add verbs somehow. The ebook refers a lot to Foursquare's API (and it approves of that as well), but looking at their API, that quite contradicts what the author says. For example:


"addcomment" is a verb, and no it is not a clearly separated call, the resource name is still there as a prefix. So would the following be the right solution then?


I think Foursquare's approach is spot on, but then why does the author say the complete opposite? That if you use verbs, don't mix it with existing resource names, and you should somehow indicate in the API docs that these calls are separate from the rest of the resource-based calls.

Thanks, Kristof

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+unsubscribe@googlegroups.com.

Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+unsubscribe@googlegroups.com.

Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 
Re: [api-craft] Web API Design 2nd Edition (APIGEE) Kevin Swiber 9/30/12 8:06 AM

On Sep 30, 2012, at 10:11 AM, Steve Klabnik <st...@steveklabnik.com> wrote:

>> That said, I can't say that the recommendations on that page make any sense
>> to me either.  I think it's bad form to build an API based on how it's
>> implemented in the back end; the API should be designed from the perspective
>> of the user of the API.
>
> Yep, :+1: from me, here, too. This is the largest problem with
> building apps in Rails; ActiveRecord + "REST"ful routes encourages a
> 1-1 mapping between tables and resources.

This is one of the many reasons I'm not a huge Rails fan.  I like software models.  As complexity increases, there exists a greater divergence between data, domain, and application models.  I hardly ever want to build my Web app or Web API on top of my data model.

I often draw parallels between advice given in Domain Driven Design and Web API modeling.  From URI design to hypermedia messages, DDD has a lot to offer.  For anyone interested, some DDD concepts worth exploring, as they pertain to Web APIs, are: Entities, Value Objects, Aggregate Roots, and Bounded Contexts.

>> I also don't think there are many (any?) cases where
>> verbs sense to identify resources.
>
> I could theoretically see some sort of resource that you only POST-ed
> to to process something being a verb, but that wouldn't be ideal, it'd
> just be acceptable.

Yeah, I don't scoff at that behavior so much.  I do prefer to make my URIs point to something with an identity (or collection of identifiable entities).  Modeling currency conversion over an API is procedural, which lends itself to this verb-based URI style.  If one were to perform currency conversion as behavior on an identifiable entity, this may look completely different.  If it's agreed this is something that should live in the API model, there are hints we can take from a DDD Domain Service.  Maybe a POST /exchange with a request body containing the right currency conversion parameters would be a good approach.  I believe it's an anti-pattern to get really granular in the API model just to avoid verbs in the URI (i.e., POST /orders/1/items/1/state { "state": "active" }).

Ah… I need to start documenting this stuff on the Internets somewhere...

--
Kevin Swiber
Re: [api-craft] Web API Design 2nd Edition (APIGEE) Mike Amundsen 9/30/12 8:08 AM
"Ah… I need to start documenting this stuff on the Internets somewhere..."

yep - would really like to see that.

mca



--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.

Visit this group at http://groups.google.com/group/api-craft?hl=en.



Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Kevin Swiber 9/30/12 8:14 AM

On Sep 30, 2012, at 10:41 AM, Glenn Block <glenn...@gmail.com> wrote:
>
> In terms of 'actions' behind each action there is a noun waiting to be discovered. The example I use (overuse) is contact management. Let's say I have a contact resource. Now I want to support the ability for contacts to connect, so I can say 'Glenn connects to Steve'. Connect is a verb, but I can flip things around and say contacts have connections, and there you go, my connections resource is born. I can now post 'Steve' to '/contacts/glenn/connections'. The uniform interface comes in nicely here because I can get connections, add connections, remove connections.
>
> Take another example, order management. Orders need to be fulfilled. Uh oh, that means I have a fulfill verb. But then I can say orders have a fulfillment resource, which I post to in order for the order to get fulfilled.
>
> My experience is you can pretty much model ANY action resourcefully in this way.

I think this is true to an extent.  I think a gut-check here is asking if the new resource you're creating is independently significant.  Can I retrieve a fulfillment?  Does that have any importance in what I'm trying to model or is it just an extra resource for the sake of "resource purity?"  This requires a lot of discipline, especially if one is coming from a strong background of procedural programming.  (This is why I harp on applying OO and DDD concepts to Web APIs.)  I think there's some leeway here.

--
Kevin Swiber
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Dan Schlossberg 9/30/12 8:43 AM
Mike, doesn't turning it into a noun imply the existence of a resource?  This might be misleading to the average developer.  I might read that as give me conversion records filtered on the following three params.

Plus, "conversion" kinda implies an action at a point in time which might not be appropriate.

It might be that changing the noun helps.  What about "convertor" instead of conversion.  That keeps the noun practice without mis-implying the existence of a conversion resource.

GET /convertor/EUR/CNY/100

But why the extra brain cycles thinking about how to accommodate a best practice so rigidly when maybe it is just general guidance.  

More specifically, what liability is introduced by just saying "convert" or maybe "convertor/convert"  If, in fact, you are asking it to perform a non-crud action.  

Considering the "principle of least surprise" and maximizing for developer love, I'd consider this:  

GET /convertor/convert/100/EUR/to/CNY

This could compliment a historic sister api like so:

GET /convertor/convert/100/EUR/to/CNY/at/5-5-2004

Had "conversion" been used the call would look like so:

GET /conversion/100/EUR/to/CNY/at/5-5-2004

Which I would expect a list conversions that matching the criteria on that date.  A completely different expectation.

Regardless, I suspect that we encroach on "the narcissism of small differences" here.  Whats ultimately important (IMO) is that the consumer of your api is given a much higher priority than has been in the past.  And that is certainly being done members of this list.

So cardboard cookies and unicorn shaped shrubbery for all!



To unsubscribe from this group, send email to api-craft+...@googlegroups.com.

Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 



--
Dan Schlossberg 
Polyglot Journeyman
[m] 678.361.6960 - @danschlossberg


Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Glenn Block 9/30/12 9:08 AM
DDD I think applies pretty cleanly in terms of a resource mapping to an aggregate. I stay pretty shy from making any OO attachments as HTTP != OO and the more OO you do the more you end up polluting your API with RPC type concepts.

As for whether it feels natural or not, that really depends on the goal. If the goal is to provide access to a system in a way that is concordant with the design of the web, then I'd say yes it make sense. 

As for retrieving fulfillment, if you think about the fulfillment resource as a processor than yes you can. When I post to fulfillment I am basically submitting a request to have the order fulfilled. I can definitely do a get on that resource to check the status of the fulfillment and see if it was fulfilled or not.




--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.



Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Glenn Block 9/30/12 9:15 AM
I am not Mike but....:-)

What do you mean by imply the existence of a resource? What do you mean by resource?

Converter would be preferable to me. It also has another benefit which is built in implied async semantics. I can do a POST to a converter and get back a 202 ACCEPTED with a location header where I can go to get the result. CONVERT however implies a synchronous operation where the server immediately returns a result.

Converter is essentially a queue or requests to convert. I could even do a GET on it to see which conversions are pending.
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Glenn Block 9/30/12 9:18 AM
" I think a gut-check here is asking if the new resource you're creating is independently significant. "

This is my opinion, but personally I see no such requirement that it be independently significant. I will introduce resources all day long if it helps clients to achieve the tasks they are trying to achieve while at the same time meets system constraints like evolvability, caching, etc.

On Sun, Sep 30, 2012 at 8:14 AM, Kevin Swiber <ksw...@gmail.com> wrote:

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.



Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Steve Klabnik 9/30/12 9:32 AM
> Mike, doesn't turning it into a noun imply the existence of a resource?

Whoah, let's get our terminology straight here: the resource _is_
`/posts` or whatever. You mean to ask "imply the existence of an
_entity_?" And the answer is no:

>  A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time.
>
> More precisely, a resource R is a temporally varying membership function MR(t), which for time t maps to a set of entities, or values, which are equivalent. The values in the set may be resource representations and/or resource identifiers. A resource can map to the empty set, which allows references to be made to a concept before any realization of that concept exists -- a notion that was foreign to most hypertext systems prior to the Web [61]. Some resources are static in the sense that, when examined at any time after their creation, they always correspond to the same value set. Others have a high degree of variance in their value over time. The only thing that is required to be static for a resource is the semantics of the mapping, since the semantics is what distinguishes one resource from another.

http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_2_1_1
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Glenn Block 9/30/12 9:37 AM
 "A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time."

I'd say "may be" as nothing requires a resource to map to an entity unless in this case you mean "entity".


--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.



Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Kristof Kotai 9/30/12 10:04 AM
Thanks for your reply Glenn,

Who says the noun has map 1 to 1 to the database? I don't think that is true at all.
The book that I was referring to says that (it is also available as a video on youtube: http://youtu.be/QpAhXa12xvU )

You can absolutely have resources which are not backed by any database or even any persistence mechanism. For example you can have a Calculator resource that is completely stateless and idempotent. You do a GET to it passing some information like this http://calculation.com/calculator/add/2+3 (no this does not exist) and it returns the result. The result never changes so it is cachable.
The main thing about using nouns as resources is it naturally fits with the uniform interface. I can check up on a thing (GET), I can add a thing (POST), I can replace a thing (PUT) and I can remove it (DELETE). 'Thing' here means noun. Now not everything supports all methods as in the example I just posted, that resource only supports GET. But that is also fine as I am not violating any thing from an HTTP perspective.
Sorry, I think you missed the point. According to the book (and I think the author is right here), the example you just gave is the reason why verbs should be used in APIs. Probably the majority of the developers will know, when they look at an API endpoint like: /calculator/add that the call will give back an error if they were to use POST, PUT or DELETE. Because it just doesn't make sense to do that. You are not deleting / updating / storing something that you could later query for example. If they were meaningful, then you would immediately come to realise that you have something that is actually being stored on the API's side. So then you should be using nouns, therefore you end up having a true resource. That's why the book suggests, that everytime you have a call like yours, (let's call it now /calculate, with a verb) then that should be separate from the rest of your calls. And if people start using verbs based on this idea, then developers can (maybe in the future) already have pre-assumptions when looking at API calls with verbs: "Oh, this is a verb, then this is some non-resource-y call, that just calculates / does something and doesn't modify my stuff on the API's side."

In terms of 'actions' behind each action there is a noun waiting to be discovered. The examplez I use (overuse) is contact management. Let's say I have a contact resource. Now I want to support the ability for contacts to connect, so I can say 'Glenn connects to Steve'. Connect is a verb, but I can flip things around and say contacts have connections, and there you go, my connections resource is born. I can now post 'Steve' to '/contacts/glenn/connections'. The uniform interface comes in nicely here because I can get connections, add connections, remove connections. 
Yes, I think this is the point. "behind every action, there is a noun waiting to be discovered". Every action on a resource will in some way result in a DB read or write. Which is why Foursquare's API looks kind of flawed.


POST /v2/venues/:id/like?set=0    // unlike
POST /v2/venues/:id/like?set=1    // like
GET  /v2/venues/:id/likes             // returns who liked the venue

Apart from the fact that they don't use DELETE for unliking (which might be better for developers, because the API becomes easier to test this way) they use a different resource for querying likes (notice the difference between "like" and "likes"). Instead of acting on the related resource (using POST, PUT, DELETE, GET) they rather introduce verbs. And I think this is the key point. Whenever you want to do actions (other than CRUD) on resources, there is always a corresponding resource that you can act on. And by specifying it in a "resouce/identifier/resource" fashion, you will no longer need to add verbs.

(I've been thinking a lot about this, and didn't think we would find this answer this quickly, thanks Glenn)
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Kristof Kotai 9/30/12 10:17 AM
Regardless, I suspect that we encroach on "the narcissism of small differences" here.  Whats ultimately important (IMO) is that the consumer of your api is given a much higher priority than has been in the past.

For me at least, and I think for other API developers as well, what's (also) important, is that by knowing all these guidelines we could somehow create a guide as well, for creating good APIs. Something that would be very close to a formal step-by-step guide. Removing as much subjective decision from the process as possible. 

Whenever someone says: "creating an API requires a design touch as well" always makes me think that this person doesn't come from a technical background... (the ebook or the video does mention this :)

I'm not saying that APIs could be built perfectly for both API developers and users as well, using only a formal process (step-by-step list), but that's what I want to find out... (Because eventually, that could lead to something very powerful: automatic API generation)


Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Glenn Block 9/30/12 10:23 AM
"Sorry, I think you missed the point. According to the book (and I think the author is right here), the example you just gave is the reason why verbs should be used in APIs."

Quite possibly :-) 

I knew the calculator example would open a can of worms. :-) My point for showing it was not to recommend this api style, but to drive home the point that you CAN have a resource that is stateless and yet still leverages HTTP for things like caching.

I don't see how using that example however correlates to you should have verbs. The calculator resource still follows all the semantics of a standard resource, it is not "different".

"Probably the majority of the developers will know, when they look at an API endpoint like: /calculator/add that the call will give back an error if they were to use POST, PUT or DELETE. "

They could, but they could also be wrong. It's perfectly reasonable to have a resource like "/calculator/adder" which I would POST to with details on what I wanted added.

"Because it just doesn't make sense to do that. You are not deleting / updating / storing something that you could later query for example."

POST actually does not have to be creating a resource. Per the HTTP spec, POST can be anything. The main thing is that the client should expect that it is not idempotent or safe. 

" If they were meaningful, then you would immediately come to realise that you have something that is actually being stored on the API's side. So then you should be using nouns, therefore you end up having a true resource. "

Not sure i follow what you mean here.

That's why the book suggests, that everytime you have a call like yours, (let's call it now /calculate, with a verb) then that should be separate from the rest of your calls. And if people start using verbs based on this idea, then developers can (maybe in the future) already have pre-assumptions when looking at API calls with verbs: "Oh, this is a verb, then this is some non-resource-y call, that just calculates / does something and doesn't modify my stuff on the API's side.""

I actually prefer developers to look at hypermedia and to be coupled to the REL rather than making assumptions based on the URI space. In documentation for a REL I can clearly say that this thing calculates. Then I free the user from knowing about my uri space, and I free my server to do what it wants.

 


--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 

Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Kristof Kotai 9/30/12 10:24 AM
" I think a gut-check here is asking if the new resource you're creating is independently significant. "

Yes, I think so too. I just can not come up with any example that could illustrate this right... (where it would not be useful to expose another resource for the developers).
It just really looks like that there is none. And that Glenn is right, by saying:

"This is my opinion, but personally I see no such requirement that it be independently significant. I will introduce resources all day long if it helps clients to achieve the tasks they are trying to achieve while at the same time meets system constraints like evolvability, caching, etc."

Thanks, Kristof
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Glenn Block 9/30/12 10:28 AM
"For me at least, and I think for other API developers as well, what's (also) important, is that by knowing all these guidelines we could somehow create a guide as well, for creating good APIs. Something that would be very close to a formal step-by-step guide. Removing as much subjective decision from the process as possible. "

I definitely see the value of guidance and it is something that helps lead to success is sorely needed. As this thread is indicative of there's a lot of debate as to what the path to success is. Personally (and i know I am biased though not alone), I think leading people toward embracing the web and away from OO thinking will have the best long term benefit.
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Glenn Block 9/30/12 10:47 AM
K, I just downloaded and actually read through the book.It's fair that you should be warned as one might consider me part of the restafari :-)

Overall I liked the guidance in the book and have no issue. I like the way it compares/contrasts against popular apis. On the issues of verbs, I'll just agree to disagree. I do agree that it's more natural for the developer to think of calling "/calculate". However I don't think whether it's natural or not trumps all other concerns. Like it or not HTTP is about resources and state. Using it in a different manner is really rowing upstream.
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Kevin Swiber 9/30/12 10:49 AM
I'd argue that the Web facilitates RPC. GET /users, POST /orders, DELETE /world-hunger.

HTTP methods dictate what kind of actions are requested at the protocol level, which is semantically significant to HTTP clients, servers, and intermediaries. They are not the API, but they provide hints on how actors should treat a request.

The URI identifies a resource on the server. This is important as it relates to how caching works.

OO talks about offering properties and behavior. This is aligned with how the Web works, IMHO. We have resource representations (objects) that offer HTML elements (properties) and provide actions through forms (behavior). The non-OO details are what make this successful over the network.

It's my belief that we need to embrace behaviors in our Web APIs. We can do this like so:

POST /customers/123
message=deactivate&reason=delinquent

This is comparable to an object receiving a message and is similar to how some programming languages interpret a method call.

I can post more on this soon...

Sent from my iPhone
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Glenn Block 9/30/12 10:53 AM
How are those RPC? That's state transfer of a resource with the intent expressed through the method. RPC is GetListOfUsers, PostOrders, DeleteWorldHunger. In that case the intent is expressed through the URI, it it is being used to express a method call on an object.

OO also talks about inheritance, would you say we should be having resources that inherit form one another? Do we have resources with virtual methods?
Re: [api-craft] Web API Design 2nd Edition (APIGEE) Mike Kelly 9/30/12 10:56 AM
On Sun, Sep 30, 2012 at 4:06 PM, Kevin Swiber <ksw...@gmail.com> wrote:
>
> On Sep 30, 2012, at 10:11 AM, Steve Klabnik <st...@steveklabnik.com> wrote:
>
>>> That said, I can't say that the recommendations on that page make any sense
>>> to me either.  I think it's bad form to build an API based on how it's
>>> implemented in the back end; the API should be designed from the perspective
>>> of the user of the API.
>>
>> Yep, :+1: from me, here, too. This is the largest problem with
>> building apps in Rails; ActiveRecord + "REST"ful routes encourages a
>> 1-1 mapping between tables and resources.
>
> This is one of the many reasons I'm not a huge Rails fan.  I like software models.  As complexity increases, there exists a greater divergence between data, domain, and application models.  I hardly ever want to build my Web app or Web API on top of my data model.
>

With respect, that is not a valid reason to not be fan of rails.
ActiveRecord is one single component of rails that is trivial to pull
out if you don't want it, after which you can employ a whole number of
different libraries for dealing with persistence, using whatever
pattern you like (Repository, DataMapper, etc.). Being Ruby, there are
very few (if any?) design approaches you can't implement in a Rails
project.

The 'magic' in rails is now decoupled from active record and is
written against 'active model' which is a fairly simple interface your
presentable objects can implement.


> I believe it's an anti-pattern to get really granular in the API model just to avoid verbs in the URI (i.e., POST /orders/1/items/1/state { "state": "active" }).

Your example is a bit of a straw man, it should really be:

POST /orders/1/items/1 { "state": "active" }

which is a decent approach because the interaction with the resource
is completely visible i.e. you are making a change to the item's
state. This is good because it enables intermediary mechanisms to take
action on the request e.g. cache-invalidation. You could step up the
visibility even more by using PUT instead of POST, thus making the
idempotency of the request visible too. If you're a pedant then you
will have to move from a partial to full representation of state, but
if you don't suffer from RFC OCD you can just stick to a partial PUT
and everything will be OK.

Cheers,
M
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Kristof Kotai 9/30/12 11:00 AM
It's my belief that we need to embrace behaviors in our Web APIs. We can do this like so:

POST /customers/123
message=deactivate&reason=delinquent

This is comparable to an object receiving a message and is similar to how some programming languages interpret a method call.

Sorry Kevin, I completely disagree with this. Call it whatever you want it, but that is not REST. 
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Kevin Swiber 9/30/12 11:03 AM

On Sep 30, 2012, at 1:53 PM, Glenn Block <glenn...@gmail.com> wrote:

How are those RPC? That's state transfer of a resource with the intent expressed through the method. RPC is GetListOfUsers, PostOrders, DeleteWorldHunger. In that case the intent is expressed through the URI, it it is being used to express a method call on an object.

It's RPC because you're calling a remote procedure that is mapped to the HTTP method + the URI. The only difference between these examples is that POST /GetListOfUsers kills caching and promotes URI driven behavior that may lose out on hypermedia benefits. Also, it's the procedural vs. OO trade off list, which has been discussed exhaustively elsewhere.

OO also talks about inheritance, would you say we should be having resources that inherit form one another? Do we have resources with virtual methods?

Are you trolling me right now? ;)

Of course not.


On Sun, Sep 30, 2012 at 10:49 AM, Kevin Swiber <ksw...@gmail.com> wrote:
I'd argue that the Web facilitates RPC. GET /users, POST /orders, DELETE /world-hunger.

HTTP methods dictate what kind of actions are requested at the protocol level, which is semantically significant to HTTP clients, servers, and intermediaries. They are not the API, but they provide hints on how actors should treat a request.

The URI identifies a resource on the server. This is important as it relates to how caching works.

OO talks about offering properties and behavior. This is aligned with how the Web works, IMHO. We have resource representations (objects) that offer HTML elements (properties) and provide actions through forms (behavior). The non-OO details are what make this successful over the network.

It's my belief that we need to embrace behaviors in our Web APIs. We can do this like so:

POST /customers/123
message=deactivate&reason=delinquent

This is comparable to an object receiving a message and is similar to how some programming languages interpret a method call.

I can post more on this soon...

Sent from my iPhone

On Sep 30, 2012, at 12:08 PM, Glenn Block <glenn...@gmail.com> wrote:

DDD I think applies pretty cleanly in terms of a resource mapping to an aggregate. I stay pretty shy from making any OO attachments as HTTP != OO and the more OO you do the more you end up polluting your API with RPC type concepts.

As for whether it feels natural or not, that really depends on the goal. If the goal is to provide access to a system in a way that is concordant with the design of the web, then I'd say yes it make sense. 

As for retrieving fulfillment, if you think about the fulfillment resource as a processor than yes you can. When I post to fulfillment I am basically submitting a request to have the order fulfilled. I can definitely do a get on that resource to check the status of the fulfillment and see if it was fulfilled or not.



On Sun, Sep 30, 2012 at 8:14 AM, Kevin Swiber <ksw...@gmail.com> wrote:

On Sep 30, 2012, at 10:41 AM, Glenn Block <glenn...@gmail.com> wrote:
>
> In terms of 'actions' behind each action there is a noun waiting to be discovered. The example I use (overuse) is contact management. Let's say I have a contact resource. Now I want to support the ability for contacts to connect, so I can say 'Glenn connects to Steve'. Connect is a verb, but I can flip things around and say contacts have connections, and there you go, my connections resource is born. I can now post 'Steve' to '/contacts/glenn/connections'. The uniform interface comes in nicely here because I can get connections, add connections, remove connections.
>
> Take another example, order management. Orders need to be fulfilled. Uh oh, that means I have a fulfill verb. But then I can say orders have a fulfillment resource, which I post to in order for the order to get fulfilled.
>
> My experience is you can pretty much model ANY action resourcefully in this way.

I think this is true to an extent.  I think a gut-check here is asking if the new resource you're creating is independently significant.  Can I retrieve a fulfillment?  Does that have any importance in what I'm trying to model or is it just an extra resource for the sake of "resource purity?"  This requires a lot of discipline, especially if one is coming from a strong background of procedural programming.  (This is why I harp on applying OO and DDD concepts to Web APIs.)  I think there's some leeway here.

--
Kevin Swiber

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.



--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Glenn Block 9/30/12 11:05 AM
"It's my belief that we need to embrace behaviors in our Web APIs. We can do this like so:

POST /customers/123
message=deactivate&reason=delinquent"

I don't have a problem with that, but that's still just a resource. I don't see how that differs from any other. There's nothing to prevent you from having the message as it's own resource either.

POST /customers/123/deactivation
reason=delinquent

Regardless, I'd surface it to the client using hypermedia. In either case the REL of the link (if there is a REL) would inform the user how to interact / what payload to send.
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Glenn Block 9/30/12 11:08 AM
It's a bit more than just killing caching and hypermedia, it's the semantics. One is coupling the client against the implementation, the other isn't. One is more discoverable, the other isn't.
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Glenn Block 9/30/12 11:09 AM
No I am not trolling you :-)
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Kevin Swiber 9/30/12 11:12 AM
I'm kind of over the "REST or not" battle, but I'm a sucker, so I'll bite...

Check Fielding's blog, titled "It's okay to use POST." Read it thoroughly with links and comments. I think he'd agree with me, but I'm not sure it really matters either way.

REST is an underspecified style. There is no authority.
Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Glenn Block 9/30/12 11:17 AM
I am also over trying to win the REST or not battle, as at the end of the day it is not the most important and it turns into a pissing contest.

What does the business need? (which includes things like evolvability, etc)
What does the user need?
How can the business deliver on both?

Those are the questions that matter....

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group, send email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
 
 

Re: [api-craft] Re: Web API Design 2nd Edition (APIGEE) Kin Lane 9/30/12 11:32 AM
Amen! 

What does the business need? (which includes things like evolvability, etc)
What does the user need?
How can the business deliver on both?

Those are the questions that matter!
Re: [api-craft] Web API Design 2nd Edition (APIGEE) Kevin Swiber 9/30/12 4:46 PM

On Sep 30, 2012, at 1:56 PM, Mike Kelly <mikeke...@gmail.com> wrote:

> On Sun, Sep 30, 2012 at 4:06 PM, Kevin Swiber <ksw...@gmail.com> wrote:
>>
>> On Sep 30, 2012, at 10:11 AM, Steve Klabnik <st...@steveklabnik.com> wrote:
>>
>>>> That said, I can't say that the recommendations on that page make any sense
>>>> to me either.  I think it's bad form to build an API based on how it's
>>>> implemented in the back end; the API should be designed from the perspective
>>>> of the user of the API.
>>>
>>> Yep, :+1: from me, here, too. This is the largest problem with
>>> building apps in Rails; ActiveRecord + "REST"ful routes encourages a
>>> 1-1 mapping between tables and resources.
>>
>> This is one of the many reasons I'm not a huge Rails fan.  I like software models.  As complexity increases, there exists a greater divergence between data, domain, and application models.  I hardly ever want to build my Web app or Web API on top of my data model.
>>
>
> With respect, that is not a valid reason to not be fan of rails.
> ActiveRecord is one single component of rails that is trivial to pull
> out if you don't want it, after which you can employ a whole number of
> different libraries for dealing with persistence, using whatever
> pattern you like (Repository, DataMapper, etc.). Being Ruby, there are
> very few (if any?) design approaches you can't implement in a Rails
> project.
>
> The 'magic' in rails is now decoupled from active record and is
> written against 'active model' which is a fairly simple interface your
> presentable objects can implement.

That's fair.  There are other reasons I'm not such a fan.  It mostly comes down to style and preference.  When writing Ruby Web apps, I prefer Sinatra.  For APIs, I might even drop down to Rack.  I want to string together my own set of components to achieve a goal.  Rails prescribes quite a bit.  I understand the benefit of that.  It's just not always my thing.  Keep in mind, I'm not against the project.  I think it's great.  I just typically find more delight going with alternatives.  My opinion on this probably doesn't matter much, anyway, since I'm doing mostly Node.js these days.  And yes, I sometimes prefer the Node HTTP module over frameworks like Express.  But… now I'm OT off the OT.  :)

>
>
>> I believe it's an anti-pattern to get really granular in the API model just to avoid verbs in the URI (i.e., POST /orders/1/items/1/state { "state": "active" }).
>
> Your example is a bit of a straw man, it should really be:
>
> POST /orders/1/items/1 { "state": "active" }
>
> which is a decent approach because the interaction with the resource
> is completely visible i.e. you are making a change to the item's
> state. This is good because it enables intermediary mechanisms to take
> action on the request e.g. cache-invalidation. You could step up the
> visibility even more by using PUT instead of POST, thus making the
> idempotency of the request visible too. If you're a pedant then you
> will have to move from a partial to full representation of state, but
> if you don't suffer from RFC OCD you can just stick to a partial PUT
> and everything will be OK.

This approach is better.  Truthfully, I'd rather not see state or status updates from the client to the API.  I typically see that as an implementation detail.  I'd rather send a { "message": "activate" } in the request body.  The server is then free to make decisions about whether that operation is valid.  Using something like {"state": "active"}, the server has to infer what the intention is based on the fields.  Having written code like that, I can say first hand that it stinks.  It's tough on the server developer and the client developer.  Doing the alternative I mentioned is the same concept as providing a task-based interface.

Zooming out a bit, in hypermedia-ville, I would probably use Siren to create an action that has a hidden "message" field with a value of "activate."  There may or may not be additional parameters involved.  The point is, the developer wouldn't need to know this exists.  They'd only need to be aware of what an action named "activate" means on an order item.

--
Kevin Swiber


Re: [api-craft] Web API Design 2nd Edition (APIGEE) Mike Kelly 9/30/12 6:19 PM
On Mon, Oct 1, 2012 at 12:46 AM, Kevin Swiber <ksw...@gmail.com> wrote:
>
> On Sep 30, 2012, at 1:56 PM, Mike Kelly <mikeke...@gmail.com> wrote:
>
>> On Sun, Sep 30, 2012 at 4:06 PM, Kevin Swiber <ksw...@gmail.com> wrote:
>>>
>>> On Sep 30, 2012, at 10:11 AM, Steve Klabnik <st...@steveklabnik.com> wrote:
>>>
>>>>> That said, I can't say that the recommendations on that page make any sense
>>>>> to me either.  I think it's bad form to build an API based on how it's
>>>>> implemented in the back end; the API should be designed from the perspective
>>>>> of the user of the API.
>>>>
>>>> Yep, :+1: from me, here, too. This is the largest problem with
>>>> building apps in Rails; ActiveRecord + "REST"ful routes encourages a
>>>> 1-1 mapping between tables and resources.
>>>
>>> This is one of the many reasons I'm not a huge Rails fan.  I like software models.  As complexity increases, there exists a greater divergence between data, domain, and application models.  I hardly ever want to build my Web app or Web API on top of my data model.
>>>
>>
>> With respect, that is not a valid reason to not be fan of rails.
>> ActiveRecord is one single component of rails that is trivial to pull
>> out if you don't want it, after which you can employ a whole number of
>> different libraries for dealing with persistence, using whatever
>> pattern you like (Repository, DataMapper, etc.). Being Ruby, there are
>> very few (if any?) design approaches you can't implement in a Rails
>> project.
>>
>> The 'magic' in rails is now decoupled from active record and is
>> written against 'active model' which is a fairly simple interface your
>> presentable objects can implement.
>
> That's fair.  There are other reasons I'm not such a fan.  It mostly comes down to style and preference.  When writing Ruby Web apps, I prefer Sinatra.  For APIs, I might even drop down to Rack.  I want to string together my own set of components to achieve a goal.  Rails prescribes quite a bit.  I understand the benefit of that.  It's just not always my thing.  Keep in mind, I'm not against the project.  I think it's great.  I just typically find more delight going with alternatives.

The problem, of course, is that any significant web app written in
sinatra basically ends up evolving into a home-brew implementation of
Rails. Reinventing Rails may well be a delightful thing to do, but is
ultimately a waste of time that doesn't deliver any real value. Same
goes for writing web request handlers in bare rack. Interested to hear
some specifics about situations that have made sense for you in the
past.

>>
>>
>>> I believe it's an anti-pattern to get really granular in the API model just to avoid verbs in the URI (i.e., POST /orders/1/items/1/state { "state": "active" }).
>>
>> Your example is a bit of a straw man, it should really be:
>>
>> POST /orders/1/items/1 { "state": "active" }
>>
>> which is a decent approach because the interaction with the resource
>> is completely visible i.e. you are making a change to the item's
>> state. This is good because it enables intermediary mechanisms to take
>> action on the request e.g. cache-invalidation. You could step up the
>> visibility even more by using PUT instead of POST, thus making the
>> idempotency of the request visible too. If you're a pedant then you
>> will have to move from a partial to full representation of state, but
>> if you don't suffer from RFC OCD you can just stick to a partial PUT
>> and everything will be OK.
>
> This approach is better.  Truthfully, I'd rather not see state or status updates from the client to the API.  I typically see that as an implementation detail.  I'd rather send a { "message": "activate" } in the request body.

hmm, afaict hat's not a great deal different.

> The server is then free to make decisions about whether that operation is valid.

this is no different whichever approach you take

> Using something like {"state": "active"}, the server has to infer what the intention is based on the fields.

How is that significantly different from inferring the intention from
your "message" property?

> Having written code like that, I can say first hand that it stinks. It's tough on the server developer and the client developer.

I've written code to deal with that on both ends and I wouldn't
describe the experience as "tough". Again, more details of your
experience might help clear this up.

> Zooming out a bit, in hypermedia-ville, I would probably use Siren to create an action that has a hidden "message" field with a value of "activate."  There may or may not be additional parameters involved.  The point is, the developer wouldn't need to know this exists.  They'd only need to be aware of what an action named "activate" means on an order item.

Or they might ignore that kind of convoluted media type control and
manually POST the activate message 'by hand', and then you're back
where you started. If your API has hundreds of clients written against
it, how can you know how many and which of the clients are dumb to
your fancy hypermedia controls?

Cheers,
M
Re: [api-craft] Web API Design 2nd Edition (APIGEE) Steve Klabnik 9/30/12 6:21 PM
> The problem, of course, is that any significant web app written in
> sinatra basically ends up evolving into a home-brew implementation of
> Rails.

:+1:, though I'm kinda biased... after doing this over and over and
over, I just suck it up and use Rails now.
http://blog.steveklabnik.com/posts/2012-01-17-moving-from-sinatra-to-rails


>> Having written code like that, I can say first hand that it stinks. It's tough on the server developer and the client developer.
>
> I've written code to deal with that on both ends and I wouldn't
> describe the experience as "tough". Again, more details of your
> experience might help clear this up.

To inject my own opinion, I don't think it's 'tough,' but I do think
it's _different_. Learning new skills can be tough, but once they're
learned, it's pretty easy. Some people think APIs in general are
'tough.' This opinion goes both ways.
Re: [api-craft] Web API Design 2nd Edition (APIGEE) Kevin Swiber 9/30/12 7:26 PM
Sent from my iPhone

On Sep 30, 2012, at 9:19 PM, Mike Kelly <mikeke...@gmail.com> wrote:

Cutting Rails chat for now. Happy to continue off list or in a different thread.

> On Mon, Oct 1, 2012 at 12:46 AM, Kevin Swiber <ksw...@gmail.com> wrote:
>>
>> On Sep 30, 2012, at 1:56 PM, Mike Kelly <mikeke...@gmail.com> wrote:
>>
>>> On Sun, Sep 30, 2012 at 4:06 PM, Kevin Swiber <kswiber@gmail
>>>
>>>
>>>> I believe it's an anti-pattern to get really granular in the API model just to avoid verbs in the URI (i.e., POST /orders/1/items/1/state { "state": "active" }).
>>>
>>> Your example is a bit of a straw man, it should really be:
>>>
>>> POST /orders/1/items/1 { "state": "active" }
>>>
>>> which is a decent approach because the interaction with the resource
>>> is completely visible i.e. you are making a change to the item's
>>> state. This is good because it enables intermediary mechanisms to take
>>> action on the request e.g. cache-invalidation. You could step up the
>>> visibility even more by using PUT instead of POST, thus making the
>>> idempotency of the request visible too. If you're a pedant then you
>>> will have to move from a partial to full representation of state, but
>>> if you don't suffer from RFC OCD you can just stick to a partial PUT
>>> and everything will be OK.
>>
>> This approach is better.  Truthfully, I'd rather not see state or status updates from the client to the API.  I typically see that as an implementation detail.  I'd rather send a { "message": "activate" } in the request body.
>
> hmm, afaict hat's not a great deal different.
>
>> The server is then free to make decisions about whether that operation is valid.
>
> this is no different whichever approach you take
>
>> Using something like {"state": "active"}, the server has to infer what the intention is based on the fields.
>
> How is that significantly different from inferring the intention from
> your "message" property?
>
>> Having written code like that, I can say first hand that it stinks. It's tough on the server developer and the client developer.
>
> I've written code to deal with that on both ends and I wouldn't
> describe the experience as "tough". Again, more details of your
> experience might help clear this up.

Given a list of property values, what is the client communicating?
What if the state is blank or null? What if I support more than one
POST operation on the resource that only requires the state?

The difference is huge. Intention revealing versus inferred operation.


>
>> Zooming out a bit, in hypermedia-ville, I would probably use Siren to create an action that has a hidden "message" field with a value of "activate."  There may or may not be additional parameters involved.  The point is, the developer wouldn't need to know this exists.  They'd only need to be aware of what an action named "activate" means on an order item.
>
> Or they might ignore that kind of convoluted media type control and
> manually POST the activate message 'by hand', and then you're back
> where you started. If your API has hundreds of clients written against
> it, how can you know how many and which of the clients are dumb to
> your fancy hypermedia controls?

You're communicating two thoughts here. I'd love to hear your
questions and opinions about Siren. Feel free to reach out to me
personally or post to the siren-hypermedia Google group.

Why do I need to know if my clients actually implement handlers for my
API's documented media type or if they're just faking it really well?
As an API provider, I'm not the Client Development Police.

I'm not sure how this would differ for any other media type. Please explain.
Re: [api-craft] Web API Design 2nd Edition (APIGEE) Mike Kelly 9/30/12 7:45 PM
On Mon, Oct 1, 2012 at 3:26 AM, Kevin Swiber <ksw...@gmail.com> wrote:
> Sent from my iPhone
>
> On Sep 30, 2012, at 9:19 PM, Mike Kelly <mikeke...@gmail.com> wrote:
>
>
>
>>
>>> Zooming out a bit, in hypermedia-ville, I would probably use Siren to create an action that has a hidden "message" field with a value of "activate."  There may or may not be additional parameters involved.  The point is, the developer wouldn't need to know this exists.  They'd only need to be aware of what an action named "activate" means on an order item.
>>
>> Or they might ignore that kind of convoluted media type control and
>> manually POST the activate message 'by hand', and then you're back
>> where you started. If your API has hundreds of clients written against
>> it, how can you know how many and which of the clients are dumb to
>> your fancy hypermedia controls?
>
> Why do I need to know if my clients actually implement handlers for my
> API's documented media type or if they're just faking it really well?
> As an API provider, I'm not the Client Development Police.

Well, if you don't know this then you have no idea of the risks
associated with any future change to your application. How do you know
whether or not a change is safe to be made? If you don't know how much
faking is going on you can't make an informed judgement. That is not a
good situation to be in, you may as well not bother with all of the
fancy-stuff-that-can-be-faked.. either that or you'll have to try and
become the Client Development Police.

> I'm not sure how this would differ for any other media type. Please explain.

Well a media type that accepts this futility can leave out unrealistic
ineffective features and end up with a simpler design that is easier
to consume.

Cheers,
M
Re: [api-craft] Web API Design 2nd Edition (APIGEE) Kevin Swiber 9/30/12 8:12 PM
How does any HTTP server truly know anything about the client other
than what's gained via the messages it sends? And why should it care?
We're drifting way off-topic.

I think I've clarified my position on the values with actions. Still
not sure what you're trying to communicate as it pertains to this
topic.

If you're interested in media type bashing, start a new thread. I
wonder if such a thread will mostly interest the minority of us who
actually care about a generic media type and that it will be peppered
with a ridiculous amount of search terms mixed with a thesaurus of
sci-fi inspired insults.

It could be a better IRC chat or Skype conversation in the interest of
low noise pollution. Just throwing it out there.

I'd be up for either if you're interested. Let me know!

Sent from my iPhone
Nouns vs. Verbs (WAS Re: [api-craft] Web API Design 2nd Edition (APIGEE) mikeschinkel 9/30/12 10:40 PM
Hi all,

At the risk of empowering "the narcissism of small differences"[1] can we talk about Nouns and Verbs? I'm channelling my 11th grade English teacher on this one and I agree with Kristof, having well established guidelines can be really helpful at times.

Can a present a strawman argument for why I think nouns make more sense for (partially) RESTful web-based APIs and then ask for others to challenge and/or support these arguments??

1.) REST requires a uniform interface, and as I understand it the uniform interface for HTTP[2] include the four verbs GET, POST, PUT and DELETE.  Correct? Incorrect? Supporting references?

2.) A key abstraction in REST is the "resource"[4] and a resource is a conceptual mapping to an entity (or set of entities.) Resources have identifiers (i.e. URIs) that identify some concept, even if that concept changes over time. Correct? Incorrect? Supporting references?

3.) "REST components perform actions on a resource by using a representation to capture the current or intended state of that resource and transferring that representation between components."[5]

Is an action like "convert" an entity?  Does it make sense that you'd want your resource to return a representation with information about an entity identified by the name "convert?"  Or would it make more sense to return information about a conversion?  From those three it seems to me that verbs would be unnatural choices to identify a resource. 

If you make the following HTTP request then isn't the representation returned information about the conversion and not about the convert (verb being used as noun here?) Correct? Incorrect? Supporting references?

GET /convert?from=EUR&to=CNY&amount=100 HTTP/1.1

I can see the argument that the entire URL including the query params represents the conversion, but isn't that more rationalizing than modeling?  Maybe I'm wrong but if so I can't see it yet.  Help me see it?

I guess I'm trying to ask you to ask yourself this: 

"Can the name you've given your URL be applied to the representation of the resource when you do a GET on it, or is the representation the result of some action taken and not about the resource itself?"  If it's the latter, isn't the resource poorly named?  

(And yes, I know URLs are "opaque" and can be meaningless but that doesn't mean we don't need to apply a named concept to them when we are architecting them. We are talking about the name you give the URL and the name you use to document the URL, even if the text of then URL itself doesn't contain meaning.)

Remembering #1 from above, that REST's uniform interface is a set of *verbs*.  Does it make sense to use this construct?

{VERB} /{verb} HTTP/1.1
 
Or isn't this more clear?

{VERB} /{noun} HTTP/1.1

Am I really being too pedantic here?  I don't know, let me know if I am.

Ignoring all that, let's look at the RESTful properties of GET, POST, PUT and DELETE:

"The GET method must be a safe method (or nullipotent) meaning that calling it produces no side-effects."[6] 

"The PUT and DELETE methods much be idempotent methods meaning that multiple identical requests should have the same effect as a single request"[7]

Does a verb like "convert" imply a safe operation?  If I convert something, haven't I caused a "side effect?"

Should I be able to cache an "action", or does it make more sense to cache the "result" on an action (or simply re-imagine it as an entity that can be cached?)

Further RESTful HTTP assumes that you can apply each of the different verbs GET, POST, PUT and DELETE to the same URL and it would behave as appropriately expected (ignoring that resources can fail process a given HTTP verb and that's okay too.) So let's consider this:

GET /convert?...
PUT /convert?...  (what are we updating?)
DELETE /convert?... (are we removing the ability to convert from the API?)

Or does this seem like it makes more sense:

GET /conversion?...
PUT /conversion (we are updating the conversion because the exchange rate has changed?) 
DELETE /conversion (we are done with it and the system can forget it.)

Yes, the previous is probably picking nits. But taken all together, is all of it really picking nits, or does all of this combine contribute to recommending nouns and recommending against verbs?

As a follow up I think my suggestion to model as "conversion" was not well considered.  I'm now thinking a "conversion" resource doesn't make sense and instead what does is an exchange rate resource. The client can easily do the math to multiple the exchange rate times the amount; you don't need a web service to multiple a number do you?

GET /exchange-rate/EUR/CNY  (get the current exchange rate for EUR->CNY)
GET /exchange-rate/CNY/EUR  (get the current exchange rate for CNY->EUR)
PUT /exchange-rate/EUR/CNY  (update to a new exchange rate for EUR->CNY)
PUT /exchange-rate/CNY/EUR  (update to a new exchange rate for CNY->EUR)
DELETE /exchange-rate/EUR/CNY  (remove exchange rate information for EUR->CNY)
DELETE /exchange-rate/CNY/EUR  (remove exchange rate information for CNY->EUR)

This also works nicely if you want to get historical information:

GET /exchange-rate/EUR/CNY/2012-01-01  (get exchange rate for EUR->CNY from Jan 1 2012)
GET /exchange-rate/CNY/EUR/2012-01-01  (get exchange rate for CNY->EUR from Jan 1 2012)

As a final aside, some people suggested that a URL might inappropriately imply a point in time. For this I'll lean on Roy again[4]:

A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time. 
...
Some resources are static in the sense that, when examined at any time after their creation, they always correspond to the same value set. Others have a high degree of variance in their value over time. 
...
For example, the "authors' preferred version" of an academic paper is a mapping whose value changes over time, whereas a mapping to "the paper published in the proceedings of conference X" is static. These are two distinct resources, even if they both map to the same value at some point in time. The distinction is necessary so that both resources can be identified and referenced independently. 

This abstract definition of a resource enables key features of the Web architecture. ... Finally, it allows an author to reference the concept rather than some singular representation of that concept, thus removing the need to change all existing links whenever the representation changes (assuming the author used the right identifier).

... The naming authority that assigned the resource identifier, making it possible to reference the resource, is responsible for maintaining the semantic validity of the mapping over time (i.e., ensuring that the membership function does not change).

All this together tells me that whenever someone presents a verb for a resource it means they probably haven't done enough analysis to discover the noun. However I would like to know if others on this list find these arguments compelling, or if you have conflicting opinions and if so why? Maybe I've just missed something key thus far?

-Mike

P.S. And yes Kin, it's about what the business and user need and being able to deliver them. Having this settled in an authoritative manner will really help us get past the petty squabbles on these types of issues so we can do exactly that. :)

[1] Looking back I wish I had read Kristof Kotai's email that started this thread better. I made a response I didn't think would be controversial, and I wasn't even correctly addressing his post.  Ah well, we all make mistakes right?
[8] http://en.wikipedia.org/wiki/Representational_state_transfer#RESTful_web_services