How to manage business logic when building a REST API - rest

I'm building a API Centric web application but I'm having trouble wrapping my head around some of the business logic.
Take this Use Case:
POST /companies -> User adds a new Company which has a Location
(Company Entity has a Location Entity which keeps the address of the company, A Company has one Location, a location can have multiple Companies)
PATCH/PUT /companies/{id} -> User edits a Company information (changes street name from Company->Location
I want my API to be able to check if there are already other companies on that Location.
If this is the case, I want the user the chose between editing the Location Entity (which will change then for all Companies on that Location) or create a new Location.
How do I send this choice back to the User in a RESTful manner?

easy :
PUT replace the entire resource if it exists or create a new resource if it doesnt exist. there is no choice to be made if you want to stay strictly REST( but you dont have to) .it's up to your users to check if the company exists with a GET before a put.
POST is suppose to replaced all the companies collection.
You could use PATCH however to update an existing company.
see : https://www.rfc-editor.org/rfc/rfc5789

The REST API or any strict service would provide a response based on a request. So the REST API can definitely respond back to the user if other companies are related to the location. But there is no way for the API to respond back with a choice. The API can respond back with some information and the user will need to make another request based on that information.
Instead, it is better to give the user the option to specify it upfront. So, the choice of whether related companies should be updated for the location is made upfront by the user as par of the request. For example, the user can specify this as a query param on the REST API and the service can take appropriate action based on that query param.

Related

REST API and ETag on individual resources of a list

Considering I have a REST API exposing a repository of users :
/users/ -> returns an array of UserModel
/users/{Id} -> returns a UserModel
I needs to implement a client application that support offline mode (API not available) that will display the list of users and the detail of each user.
I am considering to synchronize in the client app the users this way :
Get the full list of users by calling a GET on /users/ and persist the list of users
Each time a user is accessing a user profile, if REST API available, check if the user has been updated by calling the REST API and update the user details if necessary
Display the user profile
I am considering using ETag (https://en.wikipedia.org/wiki/HTTP_ETag) to implement this behavior.
My issue is that I don't want my client application to get user details one by one by calling GET /users/{Id} but in a bulk by calling GET /users/ (with some paging if needed). If I do so, the client application will get a global ETAG of the list of users, but not ETags of each user. Thus it will not be able to verify individually if a user entity is up-to-date.
As a workaround, I am considering to add an ETAG field to the UserModel of the API. This way after calling GET /users/, the client app will be able to check if a specific user has been updated by calling GET /users/{Id} with the If-None-Match <User'sETagValue> header.
I know that the solution do no stick to he HTTP 1.1 standard, and that it adds a little complexity to the ETag generation.
However, I can't find any other post describing such a solution and I am wondering if it presents major issues ? And If there are more elegant solutions ?
Thanks for your help,
Edit : WebDav standard defines a "DAV:getetag" property that looks similar to my approach (http://www.webdav.org/specs/rfc4918.html#cache-control)
The WebDAV spec is also the first thing that came to mind for me.
I don't see an issue with adding etags to the response of your collection. You might even define a collection in a more general way, so that the format is just a list of URIs, their responses and headers so your client can treat it as a list of resources that need to be written to a cache.

Handling User Preferences/States in REST API

We're starting to migrate our Website to a REST Service based system and are in the process of developing the core right now.
In our current setup a user has one or more "accounts" assigned which define what data he can see on the website. Only one account can be active for a given user at any time. Right now we store the selected account in the database and use it to filter all queries.
Now I'm not sure how to handle this properly in a REST environment. Possible solutions I found are:
Sending the requested account with every request
Storing the current account in the auth token. (We're using JWT for that)
Having the current account stored on the server and calling a specific resource to change it
Each of these has its pros and cons for our setup. Currently we're using the 3rd approach in our Website. But what would be the correct way to handle such a thing in a REST environment?
Yea the design you are dealing with is fairly bad, and what you really want to do is remove the state completely out of this system.
For that reason the first option is by far superior:
Sending the requested account with every request
If this is simply an id, there's a very simple way to do this, just prefix all your (relevant) routes / uris with this account id. For example:
http://api.example.org/accounts/{id}/...
This way the 'state' is maintained by virtue of which url you are accessing, and the server can be unaware of the state.

REST API Design: When should we use association in Uri for the resources?

We have simple e-commerce website where we have several products. Currently, each product has "Place order" button.
When user clicks on this button, we show user a form to fill Name, Mobile number and address. We don't support any monetary transaction. Once user fills this form, the order is saved to database. The order table has OrderId, ProductId, UserName, UserMobile.
We are designing API to save the user order. Should we have association b/w product and order while designing this?
For example URI to save the user order should be like:
POST /api/products/1/lead/ - The request body has user information i.e. name,mobile,address. OR
POST /api/lead/ - The request body has "PRODUCT ID" and user information i.e. name,mobile,address.
I am confused whether productId should be in request URI or in the request body? How do we make such decision?
Given that
you're first navigating to a product, before actually placing the order
the product id has nothing in common with the UserInformation model that you're posting
I'd go with the first option: POST /api/products/1/lead/
I would always go with a more shallow route for representing resources, just for the sake of simplicity. No, a nested route isn't complicated or anything, but I've seen nesting go really far. So I would keep it as shallow as possible unless...
1) You plan on having more than one thing that can have a lead. For example, you can have a lead on a product:
api/products/1/lead
or a lead on a managed service that you all provide or something (I'm reaching right now):
api/managed_services/2/lead
You could pass that info in the body always, but I imagine it would become a little cumbersome to base what resource to create based on what properties were defined in the json.
2) You plan on breaking out that route and having it go to a different service eventually. Maybe this app will have to scale substantially and a ton of users will be hitting this route moreso than any other endpoint in the system. It's a lot easier to redirect all requests to a different microservice based on the url starting with api/products than it would be redirect based on the request body.
But honestly, I don't think it matters too much. As long as it's easy for your clients to consume.

One to many relationship in REST design

I have to tables users and teams. The application logic is such that every user should belong to atleast one team(No default here, user can initially belong to any team)
If I am using RESTful APIs to create users resource, should I send the info about user's team in this API itself.
POST /api/users
Or should I make 2 requests
POST /api/users
PUT /api/teams/{id}
If I use the second logic, there is an inconsistency in database if second API is never called.
What is the right thing to do in case of REST design?
What about POST /api/teams/{id}/users.
The URI is self explanatory, you are posting a user directly in a the appropriate team.

Restful Api: User id in each repository method?

I am new to both .Net & RESTful services.
Here is the object hierarchy I have in the database: Users->Folders->Notes.
The API: GET /api/note/{noteid}
would get mapped to the repository call
NoteRepository::GetNote(userId, noteId)
Notice that I am passing on the userId to make sure that the note belongs to the logged in user for security purpose.
Is this the right approach? Meaning, every repository call would have the first parameter as the userId to check if the object being accessed belongs to the user.
Is there any better approach?
You don't need the User Id since the
GET /api/note/{noteid}
is indeed unique.
A valid scenario for adding the id would be:
GET /api/{userId}/notes
And then if you want a specific note you can:
GET /api/{userId}/notes/{noteId}
I would implement security at the entry level. whether the user has rights to perform a method on that specific resource. A role model approach would be fine.
Regards.
I would also introduce the user id in the API, because of Stateless and Cacheable constraints described in the Wikipedia REST article.
However, if I check Google Tasks REST API, they don't include the user id, same thing for Twitter API, so it seems a trend not to include the user id. If someone can shed some light I would be grateful.
UPDATE: Thinking more about it, if the noteid is unique across all users, there is no need to include the user id, so a GET /api/note/{noteid} is fine.
However, the logical parent in a restful interface would be GET /api/note/ to get a list of all notes, and here I've the objection, since the list would differ according to the user requesting it, making it non cacheable.
As for your dot net part I think that passing the userid among dot net methods is perfectly fine.