RESTful API endpoint for custom response data - rest

I am building a RESTful API where I have a resource named solar_systems. solar_sytems has id(int), system_size(int), system_cost(int) columns with many other columns.
I understand that API endpoints will be-
/v1/solar-systems - for all systems
/v1/solar-systems/{id} - for a single system
And I have to pass query params for filter, search, sorting etc.
But what will be the best practice for API endpoints if I need some kind of custom data like if I need average system_cost for each system_size.
Will it be silly, if I use - /v1/solar-systems/average-system-cost?
Please I need your opinion from your experience.

It is not silly at all to use /v1/solar-systems/average-system-cost
It is easy to get caught up in the fact that technically the average-system-cost is not a resource. But it is a piece of data that is useful to retrieve. Ultimately the goal of REST is to make APIs that are understandable and readable. A specific endpoint that gets a useful piece of data definitely falls inside that.

Will it be silly, if I use /v1/solar-systems/average-system-cost?
The REST architecture doesn't enforce any URI design (see notes below). It's totally up to you to pick the URIs that better identify your resources.
However I would probably use query parameters to select the fields to be returned in the response. Something like /v1/solar-systems?fields=average-system-cost.
Note 1: The REST architectural style, described in the chapter 5 of Roy T. Fielding's dissertation, defines a set of constraints that must be followed by the applications that follow such architecture. However it says nothing about what the URLs must be like.
Note 2: On the other hand, the examples of a popular article written by Martin Fowler explaining a model defined by Leonard Richardson suggest a URL structure that looks friendly and easy to read.

Related

What is the RESTful way to design URL that returns parent of a child resource?

I am modeling blogging REST API which has resources Blog, Post and Comment with following URLs:
/api/blogs
/api/blogs/{blogId}
/api/blogs/{blogId}/posts
and I create separate endpoint for all Posts in and their Comment`s:
/api/posts
/api/posts/{postId}
/api/posts/{postId}/comments
Given that I have postId, what is the RESTful way to get Blog for a specific Post? I have three ideas:
1. /api/posts/{postId}/blog
2. /api/blogs/parent-of-post/{postId}
3. /api/blogs?postId={postId}
To me the 1. URL looks more "prettier" but the 2. option looks more "logical" since that endpoint (eg. /api/blogs/*) is generally for blogs resources.
The third option uses query string as parameter but the issue I have with it is that this endpoint would return different type of body depending on the parameter. Eg. without parameter /api/blogs returns a collection of Blog resources, while with parameter postId it would return just single instance of Blog. I am not sure if this is good thing to do (especially because I am using ASP.NET Core and C# which has strongly typed return objects, so implementation might be awkward).
what is the RESTful way to get Blog for a specific Post?
Real answer: anything you want.
REST doesn't care what spelling conventions you use for your resource identifiers. As long as your identifiers conform to the production rules described by RFC 3986, you are good to go.
/api/blogs?postId={postId}
This is a perfectly normal choice, and turns out to be a really convenient one when you want to use general purpose web browsers, because HTML forms already have standards that make it easy to create URI with this shape.
Your other two choices are fine; they lose a point for not being HTML form friendly, but it's still easy enough to describe these identifiers using a URI template.
The third option uses query string as parameter but the issue I have with it is that this endpoint would return different type of body depending on the parameter
General purpose API consumers do NOT assume that two resources are alike just because the spellings of their identifiers overlap each other.
Which is to say, from the outside, there is no implied relationship between
/api/blogs
/api/blogs/1
/api/blogs?postId=2
so the fact that they return different bodies really isn't going to be a surprise to a general purpose consumer.
Now, your routing framework may not support returning different types from the handlers for these resources (or, more likely, may not have any "nice" way to do the routing automatically), but that's an implementation detail deliberately hidden behind the REST API facade.
Similarly, the human beings that read your access log might prefer one spelling to another, to reduce their own cognitive load.

Why we need GraphQL when we can query for a specific field in REST?

GraphQL's principle aim is to solve overfetching problem as faced by many REST APIs and it does that by querying for only specific fields as mentioned in the query.
But in REST APIs, if we use the fields parameter, it also does the same thing. So why need GraphQL if REST can solve overfetching like this?
The option to fetch partial fields is only one of the key features of GraphQL, but not the only one.
One other important advantage is the 'graphic' nature of the model. By treating your schema as a graph (that is, several resources tied together by fields), it allows you to fetch a complex response, constructed of several data types in a single API call. This is a flexibility that you don't have in a standard REST API
Both these features can obviously be done by rest as well, but GraphQL gives it in a much simpler and more intuitive way.
Take a look at this post, there's a fairly good explanation there of the advantages (and disadvantages) of GraphQL.
https://www.altexsoft.com/blog/engineering/graphql-core-features-architecture-pros-and-cons/
When you have a REST setup, you're typically returning a whole JSON representation for each endpoint. This includes all fields that you may or may not need which leads to more data usage or more HTTP calls (if you divide your RESTful API up, that is).
GraphQL on the other hand gives you exactly what you're asking for when you query with a single POST/GET request.

How to model REST API for designing a calculator service

I have been reading about the best practices for designing API's for REST services that will be exposed to customers. For example, we should use Nouns to name all the URI's exposed. Further the verbs should obey the semantics of the HTTP commands. For example, a GET request should never modify the resource, instead PUT request should be used here. I was asked this question during an interview and couldn't answer this satisfactorily-- I am designing a calculator that provides following functions, add, multiply, divide, subtract on two operands. How do I expose these methods to clients following REST principles. What URI to use for these operations? And I am not sure whether to map an add operation to GET,PUT or POST. Same for the other operations (divide, multiply etc). What are the guidelines here ?
What are the guidelines here ?
How would you do it with a web site?
That should be your first heuristic any time somebody asks you about REST. REST is an
architectural style, designed for "long-lived network-based applications that span multiple organizations". The reference application for this architectural style is the World Wide Web.
I am designing a calculator that provides following functions, add, multiply, divide, subtract on two operands. How do I expose these methods to clients following REST principles.
There are three pieces of information that the client has, which need to be communicated to the server - the operation and the two operands. One the web, the usual way to collect that sort of information is to provide a form. In this case, it might be a dropdown list of operations, and a couple of text controls to accept numbers. Because a pure function is a safe, we would probably use GET as the form method. So the HTML processing rules would take the values described by the form and transcribe them as key value pairs in the query part.
So the url would look something like
/22520c7f-6207-490e-99c9-bd1bb37f4056?op=add&firstArg=6&secondArg=9
The key generalization is to realize that the HTML form is playing the role of a URI Template - the server passes the template to the client, the client fills in the details and uses the result as the target of the request.
What this implies is that if you wanted to replace HTML with some other media type, you would need to specify a description for URI Templates, some mechanism for describing the acceptable ranges and what values might be reasonable defaults.
What URI to use for these operations?
With REST? absolutely does not matter. That's part of the point -- the client treats URI as opaque values.
URI are just identifiers; you can think of them like variable names in a program. The machines just don't care what the spellings are (so long as those spellings are consistent with RFC 3986).
Since the spelling doesn't matter, you can use whatever the local spelling conventions happen to be. A lot of people favor "hackable" URI -- the spelling of the identifier communicates useful information to the human reader.
URI are identifiers of resources; "any information that can be named can be a resource". This motivates some of the "nouns not verbs" noise -- the resources are web pages, or documents, or images, or scripts, or ... the "resource" concept is deliberately vague, so that it can be used flexibly.
I am not sure whether to map an add operation to GET,PUT or POST.
The key is to look at the semantics of the client's request. Anytime what you are doing is a query/lookup, something that is OK for the machine to do automatically for the user, then you are looking at safe semantics, and the method is likely to be GET or HEAD (special circumstances).
If we were asking the server to change the representations of its own resources, then PUT and POST come into play.
In this case, all of these operations are just doing lookups, so GET is appropriate.
(An interesting thing to note is that the none of these operations depend on server state; they are pure functions. So it might make sense to serve the client with code on demand -- javascript or some reasonable replacement -- and use the client's processor to perform the calculations rather than doing a bunch of round trips across the network).
I think one issue with the term REST is that it can have a different meaning to different people. It's possible that the interviewer has a different understanding of REST. When something like this comes up, my first inclination is to try to figure out what REST means to them. Do they mean hypermedia? Do they care about the verbs and nouns being used correctly as you mentioned? Or is in their mind REST just some HTTP endpoint that returns JSON. All of these are possible.
I would be inclined to answer the question as follows I think:
GET /add/1/2
GET /multiply/5/6
etc..
Others with much more experience than myself have answered with examples of good ways to do this.
I'd just like to point out what a really excellent question this is. I'm reading a paper by Richard Taylor and others from UC Irvine. Richard Taylor was Roy Fielding's advisor back when Fielding described REST in his PhD thesis. In a discussion comparing REST and SOAP, the paper includes this:
"...the closer the service semantics are to those of content, the more likely the service is to have a rich REST API.
...
the division between REST and SOAP may reflect a lack of design guidance; how can
services that are not content-centric, such as auction bidding
... be cleanly constructed in a REST-consistent manner?"
When they say "closer to content" they mean that the service looks more like some dynamic or static information to be retrieved by the end user, as opposed to a service looks like something that actively performs some function or calculation for the user.
They go on to provide additional guidance on this - but I haven't finished reading the paper yet, so I'll let you look that up for yourself. :-)
Search the web for: From Representations to Computations: The Evolution of
Web Architectures, Richard N. Taylor, UCI

Proper route pattern for RESTful collections with additional resources

I have been doing RESTful APIs for quite a bit (exposing and consuming 3rd parties) and I see two following patterns popping up here and there. Each has pros and cons and neither is "clean" in my opinion.
So the situation is: you have a collection resource (e.g. "assets") and you want to expose some additional resources within a collection (e.g. subresources of the collection itself, not the asset, like aggregated view endpoint or some commands).
Two patterns I see are:
People create a RESTful collection resource like /assets/${asset-id} and expose everything else they need like GET /assets/owned, GET /assets/summary, POST /assets/recheck-inventory. This looks neat and concise but introduces a clash between ${asset-id} and nouns of sub-resource URLs (e.g. asset12345 and summary are in the same place in the URL).
Others do /assets/items/${asset-id} and expose everything like GET /assets/owned, GET /assets/summary and so on. This is cleaner from routing perspective and a bit more future-proof, but adds an extra noun in the route, which leads to confusion when people are trying to do POST /assets for example.
The "best practice" guidelines I went through thus far avoid the question altogether. I also understand that REST is a convention and not the standard, and there is a universal "it depends" answer. Still, I feel like there got to be a generic recommendation here.
Hence the question is: which of two you would use?
UPDATE: to clarify, let us assume that:
/assets/owned contains entities of different types, not assets, so it is not a query and you can GET/POST/DELETE items in it.
/assets/summary is an aggregation document (e.g. report with quantities for example)
/assets/recheck-inventory is a command (i.e. POST only)
Also, we want to stick with REST principles:
route's path shall identify an entity and its state uniquely.
query parameters alter which elements are returned, but do not change the payload format.
headers are for protocol-level information and do not change service logic (i.e. presentation, security, caching, etc.)
I don't like these approaches either, but be aware, that REST does not put constraint on how to design URI structure, so you can do whatever you feel right. Apparently the developers of these webservices felt this approach right.
I would do something like the following with your URIs, since I like flat URIs much better.
/assets/items/${asset-id}
-> /assets/${asset-id}
/assets/owned
-> /assets/?owned
-> /assets/?owned=true
/assets/summary
-> /assets-summary
-> /assets/ + "Prefer: return=minimal"
You can find more about the prefer header here, but be aware, that you need to register it by the vary header if you want it to be a secondary cache key.

Rest uri design concrete example

A question about REST uri design. In the official web api tutorial i have seen the following uri:
Get a list of books by publication date: /api/books/date/2013-02-16
Following the rest principles it's not better using the following uri?
/api/books?date=2013-02-16
Thanks
There are no hard rules about were parameters should go in this case. Some place them in the URL path some add them to the query string. Do note that in REST there is no emphasis placed on the way URLs should look like. People create them hierarchically because it makes sense to do so given their domain e.g.:
/api/books/ # all books
/api/books/100 # details about the book with id=100
/api/books/mystery # all books in the mystery category
On the other hand, /api/books/date/2013-02-16 is a little bit of a stretch, again because people reason about hierarchies of resources and most of the times model their APIs as such, so given that they would expect /api/books/date to also return some books in a larger category than /api/books/date/2013-02-16 does. But in this case it doesn't really make sense, so maybe that's why you find /api/books?date=2013-02-16 to be a more natural choice.
I would also prefer /api/books?date=2013-02-16 in this case. But again, there are no hard rules on what the better choice is, see for example this: REST API Best practices: Where to put parameters?
They are equal. According to the URI standard, the path contains the hierarchical part of the identifier while the query part contains the non-hierarchical part. Now in the case of map reducing a collection you can consider the filter both hierarchical and non-hierarchical depending on your taste.
Btw. I prefer the param:value solution in the path and ending the URIs of the collections (or reduced collections) with slash, so: /api/books/date:2013-02-16/, but afaik. that is just best practice, not standard... :-)
According to the uniform interface constraint of REST, you have to apply existing standards over custom solutions, that's why we follow the URI standard in this case...