Open mozvat opened 11 years ago
I would personally lean towards moving things to the URL. I think it makes the services simpler to describe, document and test. For example, when describing to a developer in the documentation how to process a return. (I might be over-simplifying this, but bear with me for the sake of an example)
OPTION 1: generic resource (transaction) with details in the body of the POST
OPTION 2
The fields are all required, and the URL self-describes. This makes it very easy for the developer to know how to use it. reference: http://looselyconnected.wordpress.com/2011/02/01/a-proposal-for-rest-and-verbs/
That looks very slick from a REST only perspective but I have reservations. (disclaimer, I've got little rest/json experience). My thoughts are "if I have to pass in a JSON body anyway, why not just put the MerchantID there? Why make me manipulate the URL for every call I make to the endpoint? I'd prefer a simple URL. I am also thinking that the more we manipulate the URL, and the less we put in the payload, the less similar it becomes with the SOAP/XML integration we provide.
Excellent, thanks Dan. I think it is especially valid to debate whether or not the MerchantID is present in the URL. It probably does make more sense to include that in the BODY (or a HEADER field).
But I think the essence of Matt's question is whether we take the approach of A) generic 'transaction' and the details for a particular transaction (sale, return, void, preAuth, etc) are specified within the body, or B) explicit services (/payments/sale, /payments/return, /payments/void, etc) where the content of the BODY might be specific to that particular call.
I believe the later is easier to describe, document and integrate, and is the standard approach for REST. By following standard REST (and not an RPC-style implementation), we can take advantage of tools and documentation built to support REST. For example Swagger - simple self-documentation of REST APIs (https://developers.helloreverb.com/swagger/) Postman - a simple REST client (Chrome browswer plugin, https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm)
We need to agree upon this approach before we get too far down the implementation of a test instance. I believe this decision is core to our new Web Services, and if it wasn't obvious I feel strongly about the decision. :) I think this involves both product and architecture, because it is how our Developers will integrate and is under the umbrella of Developer experience.
If you want to get some background on REST, I put a couple O'Reilly e-books on the shared drive here: T:\Departments\Product\Shared\Mercury Web Services RESTful Web Services REST API Design Rulebook
Yeah I was stewing on that debate in my head over the weekend.
More thoughts…
Option A. This will work but agree it is very dependent on very good documentation because the method signature is not as easily discoverable. The developer, once integrated to the endpoint, only has to deal with formatting the proper JSON or XML for the TranType/Code. No worrying about details of REST URLs, method names/signatures. But again, must be clearly documented.
Option B. B looks great to me but would keep key/ID fields out of the URL like CouponID, ProgramID, MErchnatID, etc. Aside from simplicity, there might even be security concerns with passing around key IDs like MerchantIDs in the URL. With option B, I feel it dovetails more with our SOAP implementation. That way you can have similar method names on the SOAP end points as well so that our REST and SOAP implementations are somewhat consistent even though different technologies. I’m hoping with our focus on REST, we aren’t forgetting our SOAP implementations. A Visual Studio c# web reference to a soap end point using intellisense is so damn easy to program against. Being a Microsoft guy, I would choose that over REST.
REST /payments/Sale {MerchantID:1234; PurchaseAmount:10.50}
SOAP soap:Body
One benefit I've read to putting the IDs in the URL is that it helps with load balancing. The device handling load balancing knows to send a particular request to the app server containing that particular ID. Also, it is consistent REST pattern. (for example, see here: http://developer.netflix.com/docs/REST_API_Conventions) Regarding security we would use HTTPS for all requests, so the IDs should never be visible.
From the REST API Design Rulebook, page 18 (we don't need to be purests, just providing as part of the conversation) Rule: Variable path segments may be substituted with identity-based values Some URI path segments are static; meaning they have fixed names that may be chosen by the REST API’s designer. Other URI path segments are variable, which means that they are automatically filled in with some identifier that may help provide the URI with its uniqueness. The URI Template syntax‡ allows designers to clearly name both the static and variable segments. A URI template includes variables that must be substituted before resolution. The URI template example below has three variables (leagueId, teamId, and playerId): http://api.soccer.restapi.org/leagues/{leagueId}/teams/{teamId}/players/{playerId} The substitution of a URI template’s variables may be done by a REST API or its clients.
Awesome discussion. It is largely a religious debate because there are benefits to both sides. I'll reread everyone's thoughts here in a bit and weigh in.
For example.
http://mercuryrestapi.azurewebsites.net/api/transaction/credit/sale
or do you do
http://mercuryrestapi.azurewebsites.net/api/transaction/
.. }