how can i left out some tastypie modelresource fields when request for a list of objects - tastypie

i m a newbie to django, python and tastypie. i creating an API in which i have many resources and each resource has some other related resource.i wanted to get the related objects also when i call for a specific resource. for this In tastypie modelresources i have connected all the resource using ToOneField and ToManyField using _set and lambda function. But now the problem is that if i call the top parent resource list it fetches the complete database and returns it as the response. for example i have a topic resource, a questionresource and answerresource, where question is related to topic and answers is related to question. if i request for the available topic instances it returns all the topics, all the questions related to each topic and all the answers related to each question. what i want to do that if if i send a request for a single resource or for detail view then it should returns the related objects. for list method it should only returns the objects of that particular modelresource ....
tell me eguys how can i do this

You can accomplish what you want using the use_in parameter of the Api fields. It would look like:
related_fiedl1 = ToOneField(..., use_in='detail')
related_fiedl2 = ToManyField(..., use_in='detail')
You can use it in more complex scenarios by passing a callable (for example to show a field if a parameter is present in the request).
Another thing that's not exactly what you are asking for, but maybe more consistent, is using the full_list and full_detail parameters, so the relation fields will show a resource url in the list, and the full resource representation in the detail.

Related

Should I use GET or POST REST API Method?

I want to retrieve data about a bunch of resources. Let's say an Array of book id and the response is JSON Array of book objects. I want to send the request payload as JSON to the server.
Should I use GET and POST method?
Note:
I don't want to make multiple GET request for each book ID.
POST seems to be confusing as it is supposed to be used only when the request creates a resource or modifies the server state.
I want to retrieve data about a bunch of resources. Let's say an Array of book id and the response is JSON Array of book objects.
If you are thinking about passing the array of book id as the message body of the HTTP Request, then GET is a bad idea.
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
You should use POST instead
POST seems to be confusing as it is supposed to be used only when the request creates a resource or modifies the server state.
That's not quite right. POST can be used for anything -- see GraphQL or SOAP. But what you give up by using POST is the ability of intermediate components to participate in the conversation.
For example, for cases that are effectively read-only, you would like to use a safe method, because that allows pre-caching optimization, and automated retry of lost responses on an unreliable network. POST doesn't have extra semantic constraints, so you lose out.
What HTTP really wants is that you GET using the URI; this can be done in one of two relatively straightforward ways:
POST the ids to the server, to create a new resource (meaning that the server retains for itself a copy of the list of ids), and receive a new resource identifier back in exchange. Then GET using this new identifier any time you want to know the current representation of the results.
Encode the information you need into the URI itself. Most commonly, this is done using the query part of the URI, although that isn't strictly necessary. The downside here is that if the URI encoded representation of the array of ids is very long, you may have trouble with some implementations that enforce arbitrary URI limits.
There aren't always great answers:
The REST interface is designed to be efficient for large-grain hypermedia data transfer, optimizing for the common case of the Web, but resulting in an interface that is not optimal for other forms of architectural interaction.
If I understand correctly, you want to get a list of all of the items in a list, in one pull. This would be possible using GET, as REST returns the JSON it can by default be up to 100 items, and you can get more items if needed by specifying $top.
As far as writing back or to the server, POST would be what your looking for, this to my understanding would need to be one for one.
you are going to use a GET-Request and put your request-data (book-id array) in the data-section of your ajax (or whatever you're going to use) request. See How to pass parameters in GET requests with jQuery

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.

Rest API - Getting one-off information for an object

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.

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.

Upsert (update or insert) of resources with generated URIs in REST?

My data access layer supports the upsert operations (Spring Data's CrudRepository.save()), when the id field is not set a new record is inserted and when the id field is set it is updated.
I am wondering how to justify the additional effort required to create two separate REST methods (both on the backend and the frontend side):
POST /users, for creating a new user (and generating the URI of the newly created resource)
PUT /users/{id}, for updating the existing users
over creating just one REST method:
POST /users
Are there any benefits of having two seperate methods other than being more RESTful?
It's more clearer to using different resources for different actions.
By REST ideology - PUT Idempotent method and POST not Idempotent. So each POST request should return new item in response, but PUT should return the same item in response.
I think it's a good when behavior is expected.
But if you write documentation for your api, you can using one resource for both actions (but I would choose the first option).
The data access layer supporting upsert does not mean that the REST API should support it, too. I would not overload POST /users with two meanings. Stick to two different resources.
Edit:
POST /users has the general meaning of 'add a new instance to the resource collection'. I see no way to extend this to '... or update existing instance if an ID is given'. /users is the collection resource, not a single resource you want to manipulate. Doing a POST to a collection resource should manipulate the collection, not a single existing resource.