REST API URI design pattern: Non-hierarchical path? - rest

At work we're discussing how to structure our upcoming APIs. As of now, we're about to launch an API containing different user information endpoints, and though we'd publish it under an URI like this: api.mycompany.com/userinfo. Examples of endpoints:
api.mycompany.com/userinfo/users
api.mycompany.com/userinfo/users/{id}
api.mycompany.com/userinfo/api-docs <-- Swagger document for this particular API will be located here
This type of setup would allow us to have server1.mycompany.com host the API, and use our load balancer / proxy to forward traffic to api.mycompany.com/userinfo to server1.mycompany.com. For our next API running on server2.mycompany.com, we'll simply have our load balancer / proxy forward traffic from api.company.com/transportation to server2.mycompany.com, like this:
api.mycompany.com/transportation/cars
api.mycompany.com/transportation/cars/{id}
api.mycompany.com/transportation/api-docs <-- Swagger document for this particular API will be located here
By using "userinfo" and "transportation" in the URI, we'll have a simple way to reference our different APIs as a whole, and a simple way to publish the Swagger UI along side the actual API.
My concern with these URIs is that they're not hierarchical, but more like a way to group endpoints together. Nor is "userinfo" a resource, so compared to the REST API examples one typically comes across online, using elements such as "userinfo" and "transportation" in the path may not be according to best practices.
Does this design break any REST API design patterns? If so, how would you suggest us publishing our different APIs under a single fqdn (api.mycompany.com)? Or are there reasons not to use a single fqdn for all of our APIs?
Any input will be greatly appreciated.

REST doesn't care what spellings you use for your URI
My concern with these URIs is that they're not hierarchical, but more like a way to group endpoints together. Nor is "userinfo" a resource
Identifiers being "hierarchical" doesn't (necessarily) promise anything about a hierarchy of resources. The fact that there is a resource identified by /userinfo/users does not imply that there is also a resource identified by /userinfo. Think Key/Value store, not File System.
A Rails developer might recognize /userinfo and /transportation as namespaces.
If so, how would you suggest us publishing our different APIs under a single fqdn (api.mycompany.com)? Or are there reasons not to use a single fqdn for all of our APIs?
In a 2014 interview, Fielding offered this answer about versioning:
It is always possible for some unexpected reason to come along that requires a completely different API, especially when the semantics of the interface change or security issues require the abandonment of previously deployed software. My point was that there is no need to anticipate such world-breaking changes with a version ID. We have the hostname for that. What you are creating is not a new version of the API, but a new system with a new brand.
If you squint at that, it might imply that different API should be on different (logical) hosts.

Does this design break any REST API design patterns?
Nope. There are no "REST API design patterns". And REST doesn't say anything about what URLs should look like. REST says to treat them as opaque. There's an argument that web API URLs should be "hackable", that is, easily understandable and modifiable by a human. I'd argue that your URL structure is hackable. I'm not aware of any persuasive argument that URLs must be hierarchical in nature.

Related

Designing REST API for Different Consumers

I have an application API that is used In two scenarios:
My frontend application uses it to interact with the server
A client is using it for development of CLI tool so there is an open documentation of the API.
At start all of the endpoints were kind of generic so they have been used in both scenarios, but as my application grows i have a need to :
create special endpoints for my frontend application for optimization, for example an endpoint to some statistics screen
Change some of the basic API results structures that are not backward compatible and can break the Clients
usage.
What is the best practice to design an API to meet these needs?
How is should be design correctly so it will be adjusted
to the frontend needs and on the other side will be robust enough to not break the Client's applications?
frontend specific endpoints along with General ones?
What is the best practice to design an API to meet these needs?
This highly depends on your scenario. Is your API going to be used internally only or will it be made publicly available to an unknown number of developers and integrators? What is the expected lifetime of the API? Will it evolve?
How is should be design correctly so it will be adjusted to the frontend needs and on the other side will be robust enough to not break the Client's applications?
I recommend to commit to API contracts and use a specification for these contracts. I prefer the OpenAPI specification as it will come with a lof of benefits. Make sure you invest a lot of time and team effort (product owner, project managers, backend & frontend devs) to develop the contract in several iterations. After each iteration test the specification by mocking the API and clients before turning over to to implement your frontend app or cli client.
frontend specific endpoints along with General ones?
I would not do that, but I do not know you context. What does a frontend specific endpoint mean? If it means that as of today the endpoint should be only used by the frontend application but is of no use for the current cli client than I think it is just a matter of perspective. Make it a general endpoint and just use it by the frontend app. If it somewhat provides sensitive information that should be access only by the frontend you need to think about authentication and authorization. I recommend implementing Oauth2 for that.
create special endpoints for my frontend application for optimization, for example an endpoint to some statistics screenfrontend specific endpoints along with General ones?
I would suggest to implement all endpoints in your API and use OAuth2 as authentication. Use the scopes of the OAuth approach to manage authorization and access to different endpoints for each client (frontend app, cli).
You wrote you need to:
Change some of the basic API results structures that are not backward compatible and can break the Clients usage.
Try to avoid making breaking changes to your API. If it is used internally only you may be in control of the different clients accessing the API but even than the risk of breaking a client is high.
If you need to change existing behaviour you should think about API versioning or API evolution, which is a controversly discussed topic with a lot of different opinions and practices.
What is the best practice to design an API to meet these needs?
Design your resource representations so that they are forward and backwards compatible by design. Fundamentally, they are messages, so treat them that way; new optional fields with reasonable defaults can be added to the messages, but the semantics of a message element should never change.
If you dig through the old XML literature, you'll find references to ideas like Must Ignore and Must Forward -- those are the sorts of princples that also apply to the representations of long lived resources.
Create new resources when the existing resources cannot be conveniently extended to cover your new use case.

What is difference between REST and API?

I want to know the main difference between REST and API. Sometimes I see REST API in programming documents, then is REST or API same as REST API? I would like to know more about relation between REST, API and REST API.
REST is a type of API. Not all APIs are REST, but all REST services are APIs.
API is a very broad term. Generally it's how one piece of code talks to another. In web development API often refers to the way in which we retrieve information from an online service. The API documentation will give you a list of URLs, query parameters and other information on how to make a request from the API, and inform you what sort of response will be given for each query.
REST is a set of rules/standards/guidelines for how to build a web API. Since there are many ways to do so, having an agreed upon system of structuring an API saves time in making decisions when building one, and saves time in understanding how to use one.
Other popular API paradigms include SOAP and GraphQL.
Note that the above attempts to answer the question in regards to how the terms are commonly used in web development. Roman Vottner has offered a different answer below which offers good insights into the original definition of the term REST with more technical precision than I have provided here.
REST mostly just refers to using the HTTP protocol the way it was intended. Use the GET HTTP method on a URL to retrieve information, possibly in different formats based on HTTP Accept headers. Use the POST HTTP method to create new items on the server, PUT to edit existing items, DELETE to delete them. Make the API idempotent, i.e. repeating the same query with the same information should yield the same result. Structure your URLs in a hierarchical manner etc.
REST just is a guiding principle how to use URLs and the HTTP protocol to structure an API. It says nothing about return formats, which may just as well be JSON.
That is opposed to, for example, APIs that send binary or XML messages to a designated port, not using differences in HTTP methods or URLs at all.
There is no comparison in REST and API, REST is an API type.
API, in general, is a set of protocols deployed over an application software to communicate with other software components (Like browser interacting with servers) and provide an interface to services which the application software
offers to several live consumers.
And Rest is a form of principle which an API follows in which the server provides information whatever the client desires to interact with services.
REST basically is a style of web architecture that governs the behavior of clients and servers. While API is a more general set of protocols and is deployed over the software to help it interact with some other software.
REST is only geared towards web applications. And mostly deals with HTTP requests and responses. This makes it practically usable by any programming language and easy to test.
API is an acronym for Application Programming Interface and defines a set of structures (i.e. classes) one has to implement in order to interact with a service the API was exposed for. APIs usually expose operations that can be invoked including any required or supported arguments as well as the expected responses. Classical examples here are Corba IDL, SOAP or RMI in the Java ecosystem but also RPC-like usages of Web systems specified in documentation like Swagger or OpenAPI.
REST (REpresentational State Transfer) on the contrary was specified by Fielding in his doctoral thesis where he analyzed how the whole user interactions occurs on the Web. He realized that on the Web only a transport protocol, a naming scheme for stuff as well as a well defined exchanged format is needed to exchange messages or documents. These three parts therefore define the interface to interact with peers in such a ecosystem. The transport layer is covered by HTTP while the naming scheme is defined by URI/IRI. Contrary to traditional RPC protocols which usually only support one syntax, REST is actually independent from a particular syntax. To upkeep interoperability both client and server though need do negotiate about it, which HTTP itself supports through the Accept request and Content-Type response headers. As long as client and server support HTTP, URI/IRI and a set of negotiated representation formats, defined by backing hypermedia capable media-types, they will be able to interact with each other. In a more narrow sense REST therefore has no API other than HTTP, URI/IRI and the respective media types.
However, things are unfortunately not that easy. Most people unfortunately understand something very different in terms of REST or REST API. While URIs should not convey any semantics itself, after all they are just pointers to a resource, plenty of programmers attribute more importance to URIs than they should. Some clients i.e. will attempt to extract some knowledge off of URIs or consider URIs to return responses that represent a certain type. I.e. it may seem natural to consider an URI such as https://api.acme.org/users/1 to return a representation that describes a particular user of that particualar system. An external documentation may specify that a JSON structure is returned that follows a given template such as
{
"id": 1,
"firstName": "Roman",
"lastName": "Vottner",
"role": "Admin",
...
}
can be expected, however, such a thing is closer to RPC than it is to REST. Neither is the response self-descriptive, as required by REST, nor does it follow a representation format that follows a well defined media type that defines the syntax and each of the elements that may form a message. Clients therefore are usually tailor-made for exactly one particular system (or REST API if you will) and can't be used to interact with different systems out of the box without further manual integration/updates. External documentation such as OpenAPI or Swagger are used to describe the available endpoints, the payload-templates that a server will be able to process as well as the expected responses, depending on the input. These documentation therefore is the truth and thus defines the API a client can look up or even use to autogenerate stub classes to interact with the server-side, similar to SOAP.
I therefore don't agree with the answer given by dave. While for RPC systems or the common understood term of REST API his definition may be suitable, for actual REST architectures his explanation isn't fitting at all and thus, IMO at least, not correct either. REST isn't a collection of rules, standards and/or guidelines. It is a set of few constraints that just ensure that peers in such an architecture avoid coupling, support future evolution and become more robust to change.
API is basically a set of functions and procedures which allow one application to access the feature of other application
REST is a set of rules or guidelines to build a web API.
It is basically an architectural style for networked applications on the web which is limited to client-server based applications.
Read more at: https://www.freelancinggig.com/blog/2018/11/02/what-is-the-difference-between-api-and-rest-api/

Can I have a REST element URI without a collection URI?

a basic REST question.. I design a REST API and would like to be able to get a list of book recommendations based on a book id (i.e. client sends book id=w to server and server replies with a list of recommended books, id=x,y,z).
I see two ways to do this:
/recommendation?bookId=thetitle
/recommendation/thetitle
Option 2 seems a bit cleaner to me but I'm not sure if it would be considered good REST design? Because /recommendation/thetitle looks like an element URI, not a collection URI (although in this case it would return a collection). Also, the first part of the resource (/recommendation) would not make any sense by itself.
Thankful for any advice.
URL patterns of this kind have nothing to do with REST. None of the defining properties of REST requires readable URLs.
At the same time, one of the core principles (HATEOAS), if followed properly, allows API clients (applications, not people!) to browse the API and obtain every link required to perform a desired transition of application state or resource state based on a well known message format.
If you feel your API must have readable URLs, it's a good sign that its design probably isn't RESTful at all. This implies the need for a developer to understand the URL structure and hardcode it somewhere in a client application. Something that REST is supposed to avoid by principle.
To quote Roy Fielding's blog post on the subject:
A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server). Servers must have the freedom to control their own namespace. Instead, allow servers to instruct clients on how to construct appropriate URIs, such as is done in HTML forms and URI templates, by defining those instructions within media types and link relations. [Failure here implies that clients are assuming a resource structure due to out-of band information, such as a domain-specific standard, which is the data-oriented equivalent to RPC’s functional coupling].
Obviously, nothing stops you from actually making URLs meaningful regardless of how RESTful your API actually is. Even if it's for a purpose not dictated by REST itself (viewing the logs left by a client of a properly RESTful API could be easier for a human if they're readable, off the top of my head).
Finally, if you're fine with developing a Web API that's not completely RESTful and you expect developers of clients to read this kind of docs and care about path building, you might actually benefit from comprehensible URLs. This can be very useful in APIs of the so-called levels 0-3, according to Richardson's maturity model.
What's important in terms of REST is how you're leveraging the underlying protocol (HTTP in this case) and what it allows you to do. If we consider your examples from this perspective, /recommendation/thetitle seems preferable. This is because the use of query parameters may prevent responses from being cached by browsers (important if you're writing a JS client) or proxies, making it harder to reuse existing tools and infrastructure.

Complex domain URL structure with RESTful

I'm building a RESTful wrapper around quite complex underlaying domain. I built a domain model using UML packages and classes and derived REST-resources from the meaningful classes.
When it came to the endpint-URL design, I decided to map the package/class structure directly to URLs in order to streamline the process and have a neat traceability between my logical model (domain) and physicall implementation (REST API).
Let's say I have a following domain extract:
Admin and Work are packages, while User, Permission and Task are classes (REST Resources).
I derived the following endpoint URLs from this domain:
mydomain/admin/user -> Users collection
mydomain/admin/user/id -> User instance with id
mydomain/admin/user/id/permissions -> All permissions of the User with id
mydomain/work/task, and so on...
A collegue of mine noticed that the URLs are not optimal, mainly because these "package" parts do not map to the concrete resources. For example "admin" is not a Resource and is part of the URL. As the domain structure grows, there will be even more these intermediary non-resource-segments in the URL and he finds it wrong.
I find it nice, as URL structure itself tells something about the resource and is backed up with a complete, well documented domain model.
Is this a violation of RESTful standard?
Is this a violation of RESTful standard?
No. REST has no opinon on how an URL should look. You could use an URL like
/foo/bar/baz?qux=12
without violating any REST principle. Such an URL has no meaning for a human reader but that doesn't matter.
It is not necessary that every parts of an URL like
/foo
/foo/bar
maps to a resource. In fact is is a common misconception that RESTful URLS must follow some pattern or build rule. That is not the case.
Of courese there are best practices commonly used. One such practice would be to have collection resources like
/mydomain/admin/user
and single resources like
/mydomain/admin/user/42
But, again, that is not required by REST.
The REST architecture doesn't dictate what your URL's should look like. So, from that perspective, you're not violating any rules.
Instead, an important aspect of REST is that one should be able to use hyperlinks in order to navigate from one URL to another (something we are all used to when browsing HTML websites, but is not as common in REST APIs). Using links, consumers of your web application (wether they are humans using a web browser, or other applications that are using your API) can discover the available URLs, and the actual structure of your URLs doesn't really matter. Your URLs can even change without breaking other applications, because they will simply follow the link to the new URL.
So from a REST perspective, you could use whatever URL structure you like. As long as you provide a fixed entry point that provides a link to your users collection, the actual URL could be anything.
However, it is obviously still helpful when URLs are easy to understand and somewhat predictable. For instance, right now you have collections with a singular URL (yourdomain/admin/user) and collections with a plural URL (yourdomain/admin/user/3/permissions), which isn't very consistent. I'd suggest using only plural names, so yourdomain/admin/user becomes yourdomain/admin/users.
As for your actual question, as I mentioned this doesn't matter from a REST perspective. More important is that the URL makes clear what it represents. Something I'd take into consideration is the amount of different endpoints you're gonna have. If you are building a small application, with a small amount of endpoints, I'd keep it simple. But if you are creating a very large application with a lot of domain models, prepending them with some kind of categories sounds like a good idea.
Conclusion
URLs in a REST API should be discoverable by hyperlinks, and therefore no hard rules exist. Just make sure your URLs make sense to anybody who has to dig into them.
Some tips for usefull URLs can be found in REST-ful URI design.
You aren't following the strict definition of being RESTful; but it's not due to your colleague's concerns.
Your main challenge is that your proposal has the endpoints baked in to the client applications. A client looking for a user goes straight to /mydomain/admin/user.
But if (and when) you re-locate that endpoint, say /mydomain/admin/department/user, your clients are now broken.
The solution:
REST defines that you have one (or very few) endpoints, termed "Cool URIs", which are fixed enough that they never change.
Instead of your client going to the endpoint of /mydomain/admin/user they will take this approach:
Retrieve a root object from /mydomain (the Cool URI). => "mydomain" service object.
"mydomain" object contains a URI which has the identifier of "admin". Follow that URI.
"admin" object contains a URI which has the identifier of "user". Follow that URI.
"user" object returned (more likely a list of users).
In this respect, there is no reliance upon the client application having to know the URI format; therefore when you change the endpoints, you just change the URIs that your service embeds in the returned REST objects.
This approach to REST, where each returned object contains the URI to the next, is part of the HATEOAS principle.
If you're worried about how a client will pull back a given ID number (e.g. user 42), then that's catered for too: you can implement something like OData. So again, the URI is provided by the parent object. Instead of the client using a pre-baked endpoint like this:
/mydomain/admin/users/42
...it instead does this:
/mydomain (Cool URI)
Follow the link for "admin".
Follow the link for "users", appending ?$filter=UserId eq 42
There are also some really good concepts around solving object versioning issues, which again are difficult if you take the approach of hard-coding the endpoints upfront.
If it's any consolation, I started off defining my REST architecture around fixed endpoints (as you are), and then discovered that using a true RESTful approach is actually simpler in the long run.
Best of luck!

REST's 'resource communication mechanisms' and 'on-the-fly' improvement of a client's knowledge of them

I'm trying to come to terms with REST, as defined by Roy Fielding. Recently I've been trying to wrap my mind around:
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
The concept I'm interested in is in this quote:
The transitions may be determined (or limited by) the client’s knowledge of media types and resource communication mechanisms, both of which may be improved on-the-fly (e.g., code-on-demand).
Specifically, what is knowledge of "resource communication mechanisms", how is that knowledge described in documentation/specs and realised in an implemntation?
Then, how best to improve that knowledge 'on-the-fly'?
I think I understand addressing 'the client's knowledge of media types'.
I have some guesses (PUT,GET, etc.) but would appreciate any suggestions, examples or pointers to RESTful API's that explicitly adress the issues in that quote. If it helps I'm thinking about these issues in the context of HTTP+JSON, I appreciate REST isn't limited to HTTP+*.
The Sun Cloud API has previously been cited as good RESTful design, I couldn't see where or how it addressed these specific issues - maybe a case of not seeing the wood for the trees?
Clarification:
What puzzles me is if PUT,GET,etc. are these mechanisms, this suggests a client knows which to apply to specific hyperlinks within some <media-type>, and this seems fragile, and might suggest hypertext-links map (directly) to resources.
Resource Communication Mechanisms
By "resource communication mechanisms", I believe Roy is referring to HTTP requests and HTTP verbs. He is just saying it without being specify to HTTP because REST is not dependent on HTTP. I would say that for 99.99% of all REST services, the resource communication mechanism is documented in RFC2616.
The Sun Cloud API meets these requirements because all a client needs to understand to use the API is how to do HTTP requests and the semantics of the returned media types. For example if a client does not understand what is contained in a document of type application/vnd.com.sun.cloud.Cloud+json then it will not be able to use the API.
This is in contrast with services like OData and SData that do not define new media-types, but assume a client knows how to extract domain data out of an Atom feed and expects the client to construct URLs based on a set of rules that define the URI space. This is in direct violation of Roy's recommendations.
Improved on the fly
To be honest, I can only guess at what Roy is alluding to here. I could imagine a scenario where downloaded javascript could be used to construct an url based on user input. This could prevent the server from having to explicitly generate an url for each element in a list.
Also, certain valid transitions could be enabled or disabled on the fly based on user input. Consider the case where you do not want to enable a submit button until the user has entered all the required fields. The retrieved document contains the link to allow the transition, but the downloaded code controls when and if the user can select the link.
Downloaded code could also, be used to dynamically change the verb on a link. If you wish to edit a resource, it could do a GET, if you want to delete that resource, you do a DELETE. This would allow the representation to only contain a single link but be able to perform multiple operations.