Web API URL understanding - asp.net

I have a question about web api. My models are User -* Budget -* Item. I'm sure that a method below is not right for getting an item
http://localhost/api/items/getitem/userid/budgetid/planFact/inOut/month/
and I have to authorize user first and then return only his data, but I don't know how can I do this.
and is it right to pass a lot of parameters in uri to retrieve needed data?

Assuming this is a simple API, you should be able to get away with Basic Auth under SSL (https). Under this scheme, you'd pass the user's credentials up with every request in a header. That gives you ready access to the username for filtering out data. If this is homework, you can probably just say "and I'd use SSL in the real world" - ask your teacher.
As far as URI design, it's difficult to understand from your question what those path segments are supposed to represent, but you probably want to avoid anything that looks like a verb (such as getitem). Consider supporting these calls:
GET /items/{itemId}
// returns details on a specific item
GET /items?userId={userId}&budgetId={budgetId}
// returns a list of all items matching the query parameters
// may return just ids, limited detail, or as much detail as GET /items/{itemId}
It's not really clear what planFact and inOut are supposed to be. If month is to specify the items for a specific month, that should be a query parameter also.
It is likely that everyone will be happier if your URIs do not contain that many path segments.

Related

Different representations of one resource

When i have a resource, let's say customers/3 which returns the customer object and i want to return this object with different fields, or some other changes (for example let's say i need to have include in customer object also his latest purchase (for the sake of speed i dont want to do 2 different queries)).
As i see it my options are:
customers/3/with-latest-purchase
customers/3?display=with-latest-purchase
In the first option there is distinct URI for the new representation, but is this REALLY needed? Also how do i tell the client that this URI exist?
In the second option there is GET parameter telling the server what kind of representation to return. The URI parameters can be explained through OPTIONS method and it is easier to tell client where to look for the data as all the representations are all in one place.
So my question is which of these is better (more RESTful) and/or is there some better way to do this that i do not know about?
I think what is best is to define atomic, indivisible service objects, e.g. customer and customer-latest-purchase, nice, clean, simple. Then if the client wants a customer with his latest purchases, they invoke both service calls, instead of jamming it all in one with funky parameters.
Different representations of an object is OK in Java through interfaces but I think it is a bad idea for REST because it compromises its simplicity.
There is a misconception that making query parameters look like file paths is more RESTful. The query portion of the address is included when determining a distinct URI so the second option is fine.
Is there much of a performance hit in including the latest purchase data in all customer GET requests? If not, the simplest thing would be to do that so there would neither be weird URL params or double requests. If getting the latest order is a significant hardship (which it probably shouldn't be) there is nothing wrong with adding a flag in the query string to include it.

REST - Canonical URI vs Relative URI (from a user point of view)

I'm currently designing a service.
It is a multi-tier service, that stores data from several clients using a REST interface.
It's not clear to me how should I accept a resource id inside the URI.
Let's say the user 001 creates a resource, the first for him, but the 100th for the system.
What should I return when the user 001 makes a GET to /resource/1 (/resource/{id}). Should I display his record thus making the URI relative to the user performing the request? Or should I return the 1st for the system (denying it because it's missing the permissions to see it)?
I don't want to go deep inside the authorization stuff, but I'd like to know how should I handle this kind of situations. If I should prefer the latter then how can I make a user say "ok, give me the 1st resource I created" or "give me the 2nd ... ", "give me the last .. ", "give me the 100th resource I created"?
I dont claim to be an expert on REST but here is what I would probably do.
In your domain model, if a resource cannot exist without a user then its perfectly OK to model URL calls such as
GET /user/{userId}/resource //Gets all resources of a user
On the other hand if resources can exist without users then this link on stackoverflow gives a nice way of modelling such calls.
RESTful Many-to-Many possible?
Another thing which we did for one of our projects was that, we had the linking table (UserResource table(id,userId,resourceId) ,and we had a unique ID for that and had something like
GET /userResource/{userResourceId}
GET /userResource //Retrieve all the resources user has access to
If security is your concern , there are links on StackOverflow on how to integrate Security with Rest calls. Ideally such logic should be handled on the serverside. You typically do not want to put that logic into the REST url.
For example if you get a call for
GET /resource //Get all resources
Depending on who the user is, you return only that subset of resources he has access to.
Bottom Line : Dont build your resources around permissions.
Again, I am not an expert. Just my humble views. :-)

RESTful collections & controlling member details

I have come across this issue a few times now, and each time I make a fruitless search to come up with a satisfying answer.
We have a collection resource which returns a representation of the member URIs, as well as a Link header field with the same URIs (and a custom relation type). Often we find that we need specific data from each member in the collection.
At one extreme, we can have the collection return nothing but the member URIs; the client must then query each URI in turn to determine the required data from each member.
At the other extreme, we return all of the details we might want on the collection. Neither of these is perfect; the first can result in a large number of API calls, and the second may return a lot of potentially unneeded information.
Of the two extremes I favour the second in our case, since we rarely use this for more than one sutiation. However, for a more general approach, I wondered if anyone had a nice way of dynamically specifying which details should be included for each member of the collection? I guess a query string parameter would be most appropriate, but I don't want to break the self-descriptiveness of the resource.
I prefer your first option..
At one extreme, we can have the
collection return nothing but the
member URIs; the client must then
query each URI in turn to determine
the required data from each member.
If you are wanting to reduce the number of HTTP calls over the wire, for example calling a service from a handset app (iOS/Android). You can include an additional header to include the child resources:
X-Aggregate-Resources-Depth: 2
Your server side code will have to aggregate the resources to the desired depth.
Sounds like you're trying to reinvent PROPFIND (RFC 4918, Section 9.1).
I regularly contain a subset of elements in each item within a collection resource. How you define the different subsets is really up to you. Whether you do,
/mycollectionwithjustlinks
/mycollectionwithsubsetA
/mycollectionwithsubsetB
or you use query strings
/mycollection?itemfields=foo,bar,baz
either way they are all different resources. I'm not sure why you believe this is affecting the self-descriptive constraint.

How can I deal with HTTP GET query string length limitations and still want to be RESTful?

As stated in http://www.boutell.com/newfaq/misc/urllength.html, HTTP query string have limited length. It can be limited by the client (Firefox, IE, ...), the server (Apache, IIS, ...) or the network equipment (applicative firewall, ...).
Today I face this problem with a search form. We developed a search form with a lot of fields, and this form is sent to the server as a GET request, so I can bookmark the resulting page.
We have so many fields that our query string is 1100 bytes long, and we have a firewall that drops HTTP GET requests with more than 1024 bytes. Our system administrator recommends us to use POST instead so there will be no limitation.
Sure, POST will work, but I really feel a search as a GET and not a POST. So I think I will review our field names to ensure the query string is not too long, and if I can't I will be pragmatic and use POST.
But is there a flaw in the design of RESTful services? If we have limited length in GET request, how can I do to send large objects to a RESTful webservice? For example, if I have a program that makes calculations based on a file, and I want to provide a RESTful webservice like this: http://compute.com?content=<base64 file>. This won't work because the query string has not unlimited length.
I'm a little puzzled...
HTTP specification actually advises to use POST when sending data to a resource for computation.
Your search looks like a computation, not a resource itself. What you could do if you still want your search results to be a resource is create a token to identify that specific search result and redirect the user agent to that resource.
You could then delete search results tokens after some amount of time.
Example
POST /search
query=something&category=c1&category=c2&...
201 Created
Location: /search/01543164876
then
GET /search/01543164876
200 Ok
... your results here...
This way, browsers and proxies can still cache search results but you are submitting your query parameters using POST.
EDIT
For clarification, 01543164876 here represents a unique ID for the resource representing your search. Those 2 requests basically mean: create a new search object with these criteria, then retrieve the results associated with the created search object.
This ID can be a unique ID generated for each new request. This would mean that your server will leak "search" objects and you will have to clean them regularly with a caching strategy.
Or it can be a hash of all the search criteria actually representing the search asked by the user. This allows you to reuse IDs since recreating a search will return an existing ID that may (or may not) be already cached.
Based on your description, IMHO you should use a POST. POST is for putting data on the server and, in some cases, obtain an answer. In your case, you do a search (send a query to the server) and get the result of that search (retrieve the query result).
The definition of GET says that it must be used to retrieve an already existing resource. By definition, POST is to create a new resource. This is exactly what you are doing: creating a resource on the server and retrieving it! Even if you don't store the search result, you created an object on the server and retrieved it. As PeterMmm previsouly said, you could do this with a POST (create and store the query result) and then use a GET to retrive the query, but it's more pratical do only a POST and retrieve the result.
Hope this helps! :)
REST is a manner to do things, not a protocol. Even if you dislike to POST when it is really a GET, it will work.
If you will/must stay with the "standard" definition of GET, POST, etc. than maybe consider to POST a query, that query will be stored on the server with a query id and request the query later with GET by id.
Regarding your example:http://compute.com?content={base64file}, I would use POST because you are uploading "something" to be computed. For me this "something" feels more like a resource as a simple parameter.
In contrast to this in usual search I would start to stick with GET and parameters. You make it so much easier for api-clients to test and play around with your api. Make the read-only access (which in most cases is the majority of traffic) as simple as possible!
But the dilemma of large query strings is a valid limitation of GET. Here I would go pragmatic, as long as you don't hit this limit go with GET and url-params. This will work in 98% of search-cases. Only act if you hit this limit and then also introduce POST with payload (with mime-type Content-Type: application/x-www-form-urlencoded).
Have you got more real-world examples?
The confusion around GET is a browser limitation. If you are creating a RESTful interface for an A2A or P2P application then there is no limitation to the length of your GET.
Now, if you happen to want to use a browser to view your RESTful interface (aka during development/debugging) then you will run into this limit, but there are tools out there to get around this.
This is an easy one. Use POST. HTTP doesn't impose a limit on the URL length for GET but servers do. Be pragmatic and work around that with a POST.
You could also use a GET body (that is allowed) but that's a double-whammy in that it is not correct usage and probably going to have server problems.
I think if u develop the biz system, encounter this issue, u must think whether the api design reasonable, if u GET api param design a biz_ids, and it too long.
u should think about with UI or Usecase, whether use other_biz_id to find biz_ids and build target response instead of biz_ids directly or not.
if u old api be depended on, u can add a new api for this usecase, if u module design well u add this api may fast.
I think should use protocols in a standard way as developer.
hope help u.

Post Redirect Get pattern and use in a RESTful resource-based service when supporting searching

If I have a HTTP based RESTful service and I want to POST a search resource and use the PRG pattern for returning the URL to the search-result resource, I have to persist the search-result resource on the server.
Is this a good idea?
If I do persist the search-result resource how long is it persisted for?
Can I control this by a HTTP header of some kind?
Cheers
AWC
I don't think REST or HTTP can provide you with any guidance on this. How long the search results should persist for is purely a function of how big they are, how expensive they are to calculate, how dynamic the data is, how often the same results are requested and how much money do you want to spend on hardware to get performance.
Having said that, you could use 410 Gone to interesting effect. After a period of time you could throw away the results but keep the query parameters and saved resource url. If you get a request to that URL after the results have been thrown away, you could return 410 Gone with the query parameters in the body. The client could be prompted to decide if they want to re-issue the query.
Depending on the data, you could even hide the re-query from the client. However, depending on the type of data being returned that could be misleading to the client.
You'll notice that when you do a google search, the page with the results actually has your search in the url, and if you inspect the form on google's home page that the form is actually set to GET. So in a search scenario it is actually common to just use a single get request and not a post request, since you are using it to "GET" search results based on a particular query.
A "POST" event might be more useful when you are "POST"ing data, like when you post something on a message board. You are adding data to a database, message board, user profile, etc.
If getting the search result is a heavy tax on your system, then you might want to look into a way of caching the results based on the search term, so that whenever a get request is made for that term, the results are easier to pull together.

Resources