API Validating basket on get request - rest

What would be the best approach to handle Model State Errors for the the basket to the user that loads the basket from the API ?
Scenario:
User adds product to the basket ( basket is valid at the time of creating it )
The product is taken off ( for example has been set as not available or the price has changed since the user added to the basket )
( this can be done outside API )
Should the client make two requests:
Get The basket
Validate the basket
( a little bit RPC style )
Another way of doing it might be
extending the response view model with 'errors' that might get populated
whenever user GET it via API.
Not sure though if this is good practice though.
What would be the RESTful way of solving this problem ?
Thanks in advance for help

What would be the RESTful way of solving this problem ?
How would you do it with a web page?
It would probably be a single web page, right? Containing
a list of items in the basket, and...
a list of problems that might prevent the order from growing through
and maybe also some links to other resources that might help resolve these problems.
otherwise forms, or links to forms, to aid in performing the next step of the ordering protocol.
Another way of doing it might be extending the response view model with 'errors' that might get populated whenever user GET it via API. Not sure though if this is good practice though.
It's fine - the resource model is not the domain model is not the data model. Your "resources" are documents that support interacting with the domain.
See also: Webber 2011.

Related

REST URLs for schemas and forms

I am designing an application that will expose a REST API.
URLs for the resources themselves will look fairly standard, like below:
GET /orders //Get all orders
GET /orders?somefilter=somecriteria //search for orders
GET /orders/<orderid> //specific order
PUT /orders/<orderid> //update a specific order
POST /orders //create an order
My question is regarding resources related to these. I expect the resources will mainly be accessed through an app, but still would like want to provide basic web entry forms, as well as schemas for various resources. What url should they have?
Possible urls
//Option1
GET /forms/orders //new order
GET /forms/orders/<orderid> //edit existing order
GET /schemas/orders
//Option2
GET /orders/form //new order
GET /orders/<orderid>/form //edit existing order
GET /orders/schema
//Option3
GET /orderform //new order
GET /orderform/<orderid> //edit existing order
GET /orderschema
Option 2 doesn't seem right to me, I don't think that the form resource should share the same location on a URL as the order ID. Option 1 looks the best, but would increase the organisational complexity of the app as I couldn't keep the schemas with the rest of the code dealing with a particular resource (but that is a problem that can be solved).
Is there any accepted best practice for these? It does not have to be one of the three options above, any and all pointers would be appreciated.

What should be the Rest URL for the action "Move the competitor from team1 to to team2"

I am looking for a good URL, following REST principes, to "Move the competitor from team1 to to team2
My first guess is :
/teams/{oldTeamId}/{newTeamId}/competitors/{competitorId}/move
But it doesn't look much like REST.
Should I break it into 2 basics calls ?
Remove competitor from team1,
Add competitor to team2,
Should I remove some data from URL and pass it into the body ?
I don't really know what to do for this one.
Think about how you would implement this API as a web site.
You would probably have a link to a form -- it might be a form where the competitor, old team, and new team are all blank, or it might be a form where the competitor and old team are pre-populated. Your consumer updates the default information in the form as required, and submits it.
Notice the first point (raised by Roman Vottner as well) -- your consumer doesn't need to look at the URL at all. The client knows the HTML form processing rules, so it can create the correct HTTP request without knowing anything about the domain.
The second point is that, since the client is just submitting the form to wherever the HTML tells it to, you can make that anything you want.
One of the interesting properties of HTTP is cache invalidation. See RFC 7234, any non error response to an unsafe request will invalidate all cached representations of one resource.
So you can choose which resource gets invalidated by specifying its URI as the target of the form. In effect, it gives you a mechanism for ensuring that a consumer can read its own writes.
So some reasonable choices for the target might be
/teams/{oldTeamId}
if the team roster is the most important thing. Or
/competitors/{competitorId}
if the resource that describes the player is what is most important.
I don't really know what to do for this one.
Concentrate on make it easy to use. Your resource model is not your domain model is not your data model.
It will likely be useful to watch Jim Webber's talk REST: DDD In the Large to get clearer insights into what your "REST" API should really look like.
To answer your questions, I would not break it into two calls, I would however take some data from that (GET) url and put it in the body of your request. The request would probably be a POST or PUT (or maybe even patch), but definitely not a GET since something is actually changing.
As for a solution, how about a POST request to a /transfer. After all you are (could be) creating a new transfer which takes for example the player, their new team and maybe their old team.
I would use URL to identify the resource which in this case seems to be a competitor's team.
So would
Make the url as /competitors/{competitorId}/teams
Make the call PUT
Have a body with newTeamId and if required the oldTeamId.

REST API Design for special actions on resources

I need to design an operation “duplicate” for "articles".
My thought was: a POST on apibaseurl/articles/{id}/duplicates and returning a 200 OK with the URI of the created duplicate, which's URI however will conform to the template apibaseurl/articles/{id}.
When issuing a GET to apibaseurl/articles/{id}/duplicates however, there will not necessarily be a list of duplicates (meaning: the server will not keep track of all duplicates created for an article - the "duplicate" relationship is ignored by the server outside the scope of the request)
Questions:
is my suggested solution OK?
does it not violate any RESTful principle by having the URI of the created object point to a location not under the resource under which it was posted?
would I have to provide a client with the possibility to list all duplicates for an article?
is my suggested solution OK?
It looks fine to me.
does it not violate any RESTful principle by having the URI of the created object point to a location not under the resource under which it was posted?
No, that is not necessary. You POST to a collection resource but this does not force you to return a Location header pointing inside this collection.
would I have to provide a client with the possibility to list all duplicates for an article?
If you have a use case for this, you could provide it. But if there is no business interest in listing the articles created as duplicates of an existing article, you don't have to.
Go ahead :)

Which HTTP method to use for RESTful api for "add to cart" an existing item already in cart?

I have started designing addToCart method as HTTP POST in my RESTful API. This looks good when the client adds to cart a product first time (POST create a new entry on server). But, the same HTTP rule breaks when the client browses through the site and adds the same item again; where we should not create a new entry but only update the quantity of existing item.
Isn't using POST to update resource wrong? What is the way to implement this? or how to interpret this situation.
Note: Client/UI front which uses my api would not remember if its already there on server. Please consider any ecommerce application's addtocart as example.
I think the difficulties here are already present in how you add the original item to the cart.
When you add an item to cart, are you creating a new object (the item)? Or are you modifying an existing item (the cart)? To me it makes more sense to say the latter. POSTing an item seems like it should be reserved for a different situation, when you add a new item to your store.
Conceptually, the cart is then like a vector of all the items in your store, associated with a number (0 for almost all of them). Adding something to the cart means incrementing this number for one of the items, regardless of whether it is already more than 0.
You can use PATCH to send a part object / update to an existing object.
It's based on your model. IMHO a POST is also fine if you are modelling a new intent or cart-operation with it, which can be basically anything.

Yet more questions on RESTful URIs

Numerical IDs vs names
As an example, which of these would you choose for identifying a single transaction, from a single bank account, for a single company:
/companies/freds-painting-ltd/accounts/savings/transactions/4831
/companies/freds-painting-ltd/accounts/1/transactions/4831
/companies/62362/accounts/1/transactions/4831
You idiot, something totally different! Crikey, did you even READ Fielding's dissertation?
Now, I think the 1st one is the most readable. If I have more than one company, or if I'm someone like an accountant managing multiple companies, it's immediately clear which company, and which account, I'm looking at. It's also more bookmarkable/emailable and would prevent 'fishing' for other companies by changing the company ID. I would want transaction IDs to be unique to an account (I.e. Both 'savings' and 'current' accounts could have transaction '1'
A 'company' will be my 'top-level', or 'first class' resource. Nothing at all would ever be shared between companies. As such, it would be the ideal candidate for a shard (or 'ancestor'/'namespace' in Google App Engine parlance). So I'd only have to worry about the account names being unique within one company. Every company could have an account called 'savings'.
Not sure what the situation in the rest of the world is, though LTDs or PLCs in UK would have a unique name, there could be many 'Dave's Window Cleaning' businesses (what's know as a trading name).
The business owner(s) could potentially opt for the top level /company/company-name URI to be public, and contain some basic details like their website, contact details etc, but everything below that would NEVER be accessible by search engines.
So my thoughts/concerns are:
1) Is it reasonable, when someone signs in to add their business, to say "Sorry, 'Dave's Window Cleaning' business is taken. How about 'Dave's Window Cleaning Portsmouth' (Having taken their location in another field)? My worry with this is that, for a more well known company, you're giving away the fact that they have an account with you. Or that someone could use that form to search for names. Perhaps not a biggie.
2) The size of the company name. Would it be reasonable for a name like 'Dave's Window cleaning, gardening, and loads of other stuff'? Thus creating a URL like 'daves-window-cleaning-gardening-and-loads-of-other-stuff/'
3) How to deal with someone changing their business name - I would approach it by creating a new company with that string ID, copying over everything, then deleting the old resource. The original URI would return 404 rather than redirecting - as you can't guarantee someone else won't want to take the now unused name, or even if more than one person has used the same name in the past.
4) Should the 'real' unique ID be an number in the back end, and for every request to be handled by first doing a query for what company ID this name actually related to.
5) The impact of searching for a transaction in the persistence layer.
6) The possibility of URL rewriting, but then that wouldn't work cleanly in GAE, nor would it solve the issue of ensuring company names are unique.
RESTful webservice vs RESTful website
So, we potentially have this lovely RESTful webservice that the latest snazzy iphone/android app can use (delusions of grandeur). But what about the main website itself? I note, right now, that the URL I see at the top of my page is not 'RESTful': /questions/ask is an action. There is no 'ask' resource on the server. It's more the state of the page, the preparation for POSTing to /questions/ - or if I'm editing, PUTing to /questions/{id}
I also note that Stackoverflow has URIs like /questions/362352/name-of-the-question, and that the latter part can be omitted, and one will be redirected to it.
Should I host a completely separate webapp that consumes my lovely webservice (from the same domain)? Do I even need a separate REST server, or can I rely on content negotiation (JSON/XML) and HTTP verb to select the right method (I'm using Jersey), and return the right representation?
So I could have /companies/aboxo/ return the whole HTML page (using stringtemplate.org) if it's a GET /,text/plain or test/html, and JSON/XML for others?
But what happens for 'add/edit/delete' transaction? Would GET / /companies/freds-painting-ltd/savings/transactions/?template=add be ok (or GET ../transactions/352?template=edit), and that would return the right HTML?
Thinking about this last detail is driving me mad for some reason.
Comments, suggestions, outright ridicule - all welcome!
Marcos
Rails solves the "id vs name" problem by displaying both in the URL but using only the id to actually identify eg:
/companies/62362-freds-painting-ltd/accounts/1-savings/transactions/4831
ie - for the ones that have a "pretty url" the function that generates your path write both the id and the name... but for your router, where relevant: you strip off everything thats not the id.
incidentally, it means your customer could actually write whatever they like into the URL and it'd make no difference:
/companies/62362-i_luv_blue_turtles/accounts/1-your_mum/transactions/4831
and your router still just sees:
/companies/62362/accounts/1/transactions/4831
:)
For a cannonical URI I suggest just /transactions/{id} as I presume the transaction knows what the company and account is. Therefore, #4 :-)
Is SEO a concern? I presume you don't want random folks off the internet googling for X company's transactions?! Therefore, I would just keep names (which may change) out of the URI.