Rest API - Getting one-off information for an object - rest

Here is my example. I have a basic rest api for a Member. Simple CRUD. Project manager says "we need an endpoint that will return the remaining pension amount for that member.
I get this stuff a lot where they want a very specific piece of information about an object.I don't want to include this in the Read request as the calculation can be time consuming. So, how do I do this in a RESTful way??

You could create a new endpoint called Pension, which could have a RemainingAmount property (and probably a RemainingCurrencyIso one, too), and expose that through a link from the Member resource like so:
GET /api/member/{id}/pension

If this is a field of the user object, you could have a separate url param
?fields=RemainingAmount
In the absence of the fields param, you just return the full object.

Related

How to properly access children by filtering parents in a single REST API call

I'm rewriting an API to be more RESTful, but I'm struggling with a design issue. I'll explain the situation first and then my question.
SITUATION:
I have two sets resources users and items. Each user has a list of item, so the resource path would like something like this:
api/v1/users/{userId}/items
Also each user has an isPrimary property, but only one user can be primary at a time. This means that if I want to get the primary user you'd do something like this:
api/v1/users?isPrimary=true
This should return a single "primary" user.
I have client of my API that wants to get the items of the primary user, but can't make two API calls (one to get the primary user and the second to get the items of the user, using the userId). Instead the client would like to make a single API call.
QUESTION:
How should I got about designing an API that fetches the items of a single user in only one API call when all the client has is the isPrimary query parameter for the user?
MY THOUGHTS:
I think I have a some options:
Option 1) api/v1/users?isPrimary=true will return the list of items along with the user data.
I don't like this one, because I have other API clients that call api/v1/users or api/v1/users?isPrimary=true to only get and parse through user data NOT item data. A user can have thousands of items, so returning those items every time would be taxing on both the client and the service.
Option 2) api/v1/users/items?isPrimary=true
I also don't like this because it's ugly and not really RESTful since there is not {userId} in the path and isPrimary isn't a property of items.
Option 3) api/v1/users?isPrimary=true&isShowingItems=true
This is like the first one, but I use another query parameter to flag whether or not to show the items belonging to the user in the response. The problem is that the query parameter is misleading because there is no isShowingItems property associated with a user.
Any help that you all could provide will be greatly appreciated. Thanks in advance.
There's no real standard solution for this, and all of your solutions are in my mind valid. So my answer will be a bit subjective.
Have you looked at HAL for your API format? HAL has a standard way to embed data from one resources into another (using _embedded) and it sounds like a pretty valid use-case for this.
The server can decide whether to embed the items based on a number of criteria, but one cheap solution might be to just add a query parameter like ?embed=items
Even if you don't use HAL, conceptually you could still copy this behavior similarly. Or maybe you only use _embedded. At least it's re-using an existing idea over building something new.
Aside from that practical solution, there is nothing in un-RESTful about exposing data at multiple endpoints. So if you created a resource like:
/v1/primary-user-with-items
Then this might be ugly and inconsistent with the rest of your API, but not inherently
'not RESTful' (sorry for the double negative).
You could include a List<User.Fieldset> parameter called fieldsets, and then include things if they are specified in fieldsets. This has the benefit that you can reuse the pattern by adding fieldsets onto any object in your API that has fields you might wish to include.
api/v1/users?isPrimary=true&fieldsets=items

Is it considered RESTful if single POST requests create multiple resources?

We have customers API that takes {customer-name, customer-mobile, customer-email} and creates customer in the database.
We also have order API that takes {productId, customer-name, customer-mobile, customer-email}.
The code for order API:
First creates customer based on {name,mobile,email} passed in the order API and return back customerId.
The {productId, customerId} further gets saved in the database in the order table.
Is this restful practice that one API is internally first creating some other resource?
Please note that its an over simplified example where API expects only one type of product in the order API.
It's fine for a single POST call to result in multiple resources being created. It's not generally the best idea but there are use cases where it makes sense - example cases might include (usual legal disclaimer... not limited to...)
the POST method is to the parent resource of all the created resources. So, a POST /accounts call might result in an /accounts/<accountId> resource being created but also an /accounts/<accountId>/tweets resource. In this instance, the /accounts/<accountId> parent is the 'actual' resource being created.
the POST method might create multiple resources representing multiple ways in which the resource may interact with other parts of the system. So, a POST /accounts response might create resources under /accounts/<accountId> and /users/<accountId> (because an account is-a user and user id are a super set of account ids, for arguments sake). However, the client really only gets told about the one under the '/accounts' path (via the Location header). The other created resource is basically a side-effect.
The key point, really, is that the POST method returns a single Location header - representing the 'primary' resource created - and that subsequent 'GET's on that URI are capable of locating any the other resources via links.
If you find yourself in a situation where creating multiple resources via a single POST request results in you having to return different values for the Location header, then something's wrong with your resource breakdown. It should be clear that a 'POST' will always create one particular type of resource, a URI to being returned in the header. Other resources might be created as side-effects.

Design a REST API in which a search request can take parameters for multiple Queries

I have to design a REST API in which a search request can take parameters for multiple Queries ( i.e. when the client make a call using this API, he should be able to send parameters to form multiple queries).
We have an existing API where we are using GET and it takes multiple parameters which together forms a single Query and then this API call returns the response for this query.
e.g. currently I can pass firstName, lastName, age etc in the request and then get back the person.
But now I have to enhance this service(or have a separate service) where I should be able to send parameters like firstName1, lastName1, age1 to search person1 ; firstName2, lastName2, age2 to search person2 and so on.
Should I use POST for the new API and then send list of parameters(params for query1, params for query2 and so on)?
Or is there a better approach.
We are using Spring Boot for REST implementation.
Its better to use POST because GET is good for 2,3 parameter but when you have a set of parameter or object then POST is Good.
The best thing to do here will be do POST and then return a JSON object with all the details of the Person in an array.
That way it will be faster and you would not have to deal with long urls for GET.
Also GET has limitations regarding the length of the request whereas there is no such limitation in case of POST.
It is really hard to give a right answer here. In general sending a GET request does have the advantage that you can leverage caching easily on a HTTP level, e.g. by using products like varnish, nginx, etc. But if you already can forsee that your URL including all params you'll have to send a POST request to make it work in all Browsers.
RESTfull architecture should respect the principle of addressability.
Since multiple users can be accessed through a unique request, then ideally this group of user should get an address, which would identify it as a resource.
However I understand that in the real world, URIs have a limited length (maximum length of HTTP GET request?). A POST request would indeed work well, but we lose the benefit of addressability.
Another way would be to expose a new resource : group,.
Lets suppose that your current model is something like this :
.../users/{id}
.../users/search?{arg1}={val1};{arg2}={val2}
You could eventually do something like :
.../users/groups/
.../users/groups/{id}
.../users/search?group={id}
(explanation below)
then you could split your research in two :
first a POST on .../users/groups/ with, as proposed by other response, a JSON description of the search parameters. This request could scan the .../users/groups/ directory, and if this set of parameters exists, return the corresponding address .../users/groups/{id}. (for performance issues you could for instance define {id} with a first part which would give the number of users requested).
Then you could make a request for this group with a GET with something like this : .../users/search?group={id}.
This approach would be a bit more complex to implement, but is more consistent with the resource oriented paradigm.

REST API Design with many input parameters including collections

I need to design and implement a REST API where users need to pass many input parameters. Out of those input parameters few are collection of an integer, few of them are date strings etc. After getting all these parameters I need to return unique id in the response. What method type (PUT, POST or GET) I should use in order to implement this API? How can I pass all these parameters to the API? I don't want users to format input parameter list into XML or JSON and post as a request body.
I appreciate if anybody can help on this topic.
POST is for creating new resources.
PUT is for updating existing resources. A PUT call should be idempotent, i.e. issuing the same request twice will end in no side effects.
To get an overall clue on how RESTful services work, read this article.
And yes, if you want your users to submit a complex set of parameters JSON/XML is the best way to go of course.

Make a RESTful API call that updates many related entities

We have a model that looks like this
Login <- Email Addresses <- Person -> Teen
And a stored procedure which takes some properties from teen, some from person, and some from Login, and creates a new teen, returning a person entity.
Looking from a classic RPC perspective, this is easy...just expose a method InsertTeen and have it call the stored procedure.
I've been trying to wrap my head around the RESTful idea of having URLs as my resources (nouns), and the only actions being HTTP actions (verbs). Obviously, a URL like /api/InsertTeen is not RESTful at all.
But here I'm not dealing with any particular resource.
The only thing I can thing of here would be to expose a resource like insertTeenRequest.
Are there any other ideas of how to do this? Am I being too much of a "zealot"?
If you want to be really RESTful, you should use several requests to your API in this case. For example first you create Teen with POST to /api/teens/, then create Person with POST to /api/persons/ and so on.
Pretty new to REST myself, but my thinking is that here you would use a "POST" with the body of the request containing the data needed to create a 'Teen', in whatever format you are using, usually JSON or XML. Here, I'm not sure whether you treat Teens as Persons with additional properties, or a Teen is modeled as an entity itself:
<person login="abc" email="abc#foo.com">
<person-property-1>value1</person-property-1>
<person-property-2>value2</person-property-2>
<teen>
<teen-property-1>value3</teen-property-1>
<teen-property-2>value4</teen-property-2>
</teen>
</person>
or
<teen login="abc" email="abc#foo.com">
<person-property-1>value1</person-property-1>
<person-property-2>value2</person-property-2>
<teen-property-1>value3</teen-property-1>
<teen-property-2>value4</teen-property-2>
</teen>
Regarding the URI, I believe the segments should be nouns rather than verbs since the URI is supposed to address a resource, so /api/teens rather than /api/InsertTeen.
/api/teens with an HTTP GET would return a list of all Teens, and /api/teens with an HTTP POST would insert a new Teen. To round out the CRUD operations, /api/teens/{id} using HTTP GET would return a specific Teen, /api/teens/{id} with an HTTP PUT would update a Teen using the values passed in the request body, and /api/teens/{id} called with HTTP DELETE would delete the specified Teen.
Edit
Read over your question again, and I may have misunderstood. If you aren't treating 'teens' as a resource, but only 'people', then I would consider /api/people with an HTTP POST, and depending on the values passed in the body of the request, do whatever is appropriate to store that 'person'. So, if the request contained 'teen' values, call your stored procedure that creates a 'Teen' and returns a 'Person'.
HTH