Api naming in microservices design - rest

Let's say that there are two microservices representing the resources orders(/orders) and customers(/customers). My requirement is to get all the orders made by a customer.
Had it been a monolithic application, I would have modeled my uri as /customers/{id}/orders. This would have hit the customers resource and made an in-memory service call to get the corresponding orders.
Now, in case of microservices, this isn't possible. So, is the only way to get the orders is to make a remote service call or is there a better way of doing it?
Can we create another resource with the representation /ordersByCustomers/{customerid}?

You can pass some query parameters as filters (this is the most common way I've seen). For example
/orders?customerId=123
I think that's quite clear, that you want to retrieve all customer orders filtered by customer id. In the same way you can add pagination or other filters.
The important thing to remember is that you want the order resource, so the URL should remain the same. I'm mentioning this, because this has been the most difficult thing for me to change... to think about resources rather than remote calls.

In general you should beware of using endpoint that are more or less similar to the one you suggested:
/ordersByCustomers/{customerid}
Why? Because this is not RESTful in general (even in microservices environment) and make the API difficult to understand and you by the consumers. What if you need orderByWhatever? Will you be introducing new endpoint every single time you need a new set of data? Try to avoid so opinionated endpoints.
What #Augutsto suggested is fully correct. If you're afraid of having a complicated logic in GET request this is the situation where you can break REST rules. I mean introducing:
POST /orders/filter/
Where all the filtering logic will be passed in requests body - so it's easier to carry complicated logic as well.

Related

RPC vs restful endpoints

I've spent more time than I'd like to admit trying to understand the differences between RPC and restful endpoints. In fact, after going down this rabbit hole, I'm not even sure I fully understand what RPC is anymore. And I'm not alone. I see countless messages repeatedly asking for clarification.
Here's my understanding so far:
RPC and restful endpoints are largely conceptual in nature only. There are no standards.
Both are ways of invoking a function on a remote server.
In the case of restful endpoints, we map HTTP methods to CRUD operations on a resource.
In the case of RPC, we're concerned w/actions on an object.
However, in both cases, we're addressing remote method invocation.
I've read some folks say restful shouldn't be stateful and if it is, it's not restful. But aren't most restful endpoints using state via sessions? I mean, I'm not going to let just anyone delete data w/o being logged in.
And I've also read that functions like domain(.)com/login isn't restful b/c it's an action. This seems to make sense, but since I'm not writing my functions any differently on my server than I would a simple restful function, does it really matter what we call them -- restful vs. RPC.
I truly just don't understand what I'm missing and no posts thus far on StackOverflow appear to address this confusion.
Hoping someone can provide some insight using the above as a guide for understanding. Thanks in advance.
It's an amazing question. There is a huge difference between REST and RPC approaches, I'll try to explain it.
RPC just lets you call some remote computer to make some job. It can be any job, and it can have any inputs and outputs. When you design API, you just define how to name this job operation and which inputs and outputs it will have.
Step 1. Just RPC
For example, you could have operation foo with one input and two outputs like that (I will use JSight API notation because it supports both RPC and REST API types):
JSIGHT 0.3
URL /rpc-api
Protocol json-rpc-2.0
Method foo
Params
{
"input-1": 123 // some integer
}
Result
{
"output-1": 123, // some other integer
"output-2": "some string"
}
When you design your RPC API you can use as many such operations as you want.
So, what's the problem with this? Why do we need REST, if we already have RPC?
The problems are the following:
When you look at the method foo definition you do not have the slightest idea, what it does.
When you design RPC APIs you have absolute freedom, but freedom often can be a bad thing. Because people think in different fashions. You could think, that your API is easy and elegant, but other people would not think so.
Step 2. Standardized RPC
If you are an experienced API designer and you use the RPC style, you will try to follow some pattern to avoid the two faults mentioned above. For example, let's imagine, that your foo method returns a customer entity. Then you will never call it like foo, you will call it getCustomer, like this:
JSIGHT 0.3
URL /rpc-api
Protocol json-rpc-2.0
Method getCustomer
Params
{
"input-1": 123 // some integer
}
Result
{
"output-1": 123, // some other integer
"output-2": "some string"
}
Ok! Now when you just look at this description, you can say, that this method returns a customer; that parameter input-1 is some filter, most possibly, ID; and output-1 and output-2 are some customer properties.
Look, just using the standard way of naming the method, we made our API much more easy-to-understand.
Still, why do we need REST? What's the problem here?
The problem is, that when you have dozens of such RPC methods, your API looks messy. E. g.:
JSIGHT 0.3
URL /rpc-api
Protocol json-rpc-2.0
Method getCustomer
Method updateCustomer
Method getCustomerFriends
Method getCustomerFather
Method askCustomerConfirmation
# etc...
Why it is not easy to understand this bunch of methods? Because it is not the way our brain works. Our brain always groups actions by entity. You naturally think about an entity, and then about actions, you can do with it. E. g. what you can do with a cup? Take, hide, break, wash, turn over. And brain rarely thinks firstly about actions and then about entities. What can I take? Cup, ball, ice cream, ticket, wife. Not very natural.
So, what is REST about?
Step 3. REST
REST is about grouping entities and defining the most standard actions with these entities.
In IT we usually create, read, write, or delete entities. That's why we have POST, GET, PUT, and DELETE methods in HTTP, which is de facto the only implementation of the REST style.
When we group our methods by entities, our API becomes much clearer. Look:
JSIGHT 0.3
GET /customer/{id}
PUT /customer/{id}
GET /customer/{id}/friends
GET /customer/{id}/father
POST /customer/{id}/ask-confirmation
It is much easier to perceive now than in the RPC-style example above.
Conclusion
There are a lot of other issues, concerning differences between RPC and REST. REST has its faults as well as RPC. But I wanted to explain to you the main idea:
REST is a standard, that helps you to organize your API in a user-friendly fashion, that is comfortable for the human brain, so any developer can quickly capture your API structure.
RPC is just a way of calling remote operations.
All the examples above are gathered here: https://editor.jsight.io/r/g6XJwjV/1
I truly just don't understand what I'm missing
Not your fault, the literature sucks.
I think you may find Jim Webber's 2011 guidance enlightening.
Embrace HTTP as an application protocol. HTTP is not a transport protocol which happens to go conveniently through port 80. HTTP is an application protocol whose application domain is the transfer of documents over a network.
HTTP, like remote procedure calls, is a request/response protocol. The client sends a message to the server, the server sends a message back. Big deal.
But in the REST architectural style, we're also following the uniform interface constraint. That means (among other things) that everybody understands requests the same way, and everybody interprets responses the same way.
And that in turn means that general purpose components (browsers, web crawlers, proxies) can understand the request and response messages, and react intelligently to those messages, without needing to know anything at all about the specialization of a particular resource.
In the case of HTTP, we're passing messages about the domain of documents; if I want information from you, I ask for the latest copy of your document. If I want to send information to you, I send you a proposed modification to your document. Maybe you respond to my modification by creating a new document and you tell me to go look at that. And so on.
Useful business activity, then, becomes a side effect of manipulating these documents. Or, expressed another way, the document metaphor is the facade we present to the world.
And I've also read that functions like domain(.)com/login isn't restful b/c it's an action.
See above: the literature sucks.
Consider this resource identifier: https://www.merriam-webster.com/dictionary/login
Does it work like every other resource identifier on the web? Yes. The browser knows how to make a request to GET this resource, and when Merriam-Webster answers that the browser should instead look at https://www.merriam-webster.com/dictionary/log%20on then it fetches that resource as well.
The fact that "login"/"log on" are intransitive English verbs does not matter; it's an identifier, and that's all the browser needs to know.
Alternatively, consider this: URL shorteners work.
Resource identifiers are a lot like variable names in a computer program; so long as the identifier satisfies the production rules of your language, you can use anything you want. The machines don't care.
The key idea is that resources are not actions, they are "information that can be named". https://www.merriam-webster.com/dictionary/log%20on is the name of the document that describes Merriam-Webster's definition of the verb "log on".
Since the machines don't care what names we use, we can use the extra freedom that offers us to choose names that make life easier for people we care about.
I've read some folks say restful shouldn't be stateful and if it is, it's not restful. But aren't most restful endpoints using state via sessions?
Stateless communication is a REST architectural constraint.
each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server.
Cookies are one of the corners where HTTP failed to satisfy the stateless communication constraint.
I'm not going to let just anyone delete data w/o being logged in.
Not a problem: every HTTP request carries its own Authorization metadata; you aren't supposed to "remember" previous messages in the conversation. Instead, you verify the provided credentials every time.

Restfull api design

Im currently facing the following scenario in designing an api and i'm curious what is the best choice. We have multiple levels in our routes e.g.:
GET group/:id
GET group/type/
The problem here occurs when someone is doing a GET-request on e.g. group/type, the ../type is intrepreted as the id. Which does make sense if you consider the GET on group/ only refers to a single group. Then the correct route for the type would be group/:id/type.
However, a group can have multiple types and we need a route to simply query all group types.
What is the restful way of implementing this.
Should one do a GET /grouptypes route or some nasty regex stuff to test if /group/gibberish is a subroute or id ?
I don't ask for some hacky ways of implementing a solution, i'm just asking what would be the best design choice if we design a restful api.
I am tagging this as Express.js question since we do implement the api in express. Nevertheless i think the above behaviour is what one would expect from a routing mechanism in frameworks of such kind.
I assume you routing code looks like this example, or somewhat very similar to:
...
router.get('/group/:id', middleware, controller, ...);
router.get('/group/type', middleware, controller, ...);
...
So the only thing you need to make it work, just swap these lines with each other:
...
router.get('/group/type', middleware, controller, ...);
router.get('/group/:id', middleware, controller, ...);
...
The reason is that express uses the first matching route among registered routes. Taking that fact, it is quite easy to understand that since request to the /group/type route matches both schemes - the first registered will be used.
From the REST perspective, having /group/:id for getting information about particular group is completely good. Also it is completely OK to have some specific routes like /group/total or /group/stats or whatever else for getting some general data related to all groups.
I don't know what is the actual functionality of your /group/type route, but if it is endpoint for getting, for example, stats about types of all groups - that is fine.

REST Best practise for filtering and knowing the result is singular: List or single?

Variety of REST practises suggest (i.e. 1, 2, 3) to use plurals in your endpoints and the result is always a list of objects, unless it's filtered by a specific value, such as /users/123 Query parameters are used to filter the list, but still result in a list, nevertheless. I want to know if my case should 'abandon' those best practices.
Let's use cars for my example below.
I've got a database full of cars and each one has a BuildNumber ("Id"), but also a model and build year which combination is unique. If I then query for /cars/ and search for a specific model and year, for example /cars?model=golf&year=2018 I know, according to my previous sentence, my retrieve will always contain a single object, never multiple. My result, however, will still be a list, containing just one object, nevertheless.
In such case, what will be the best practise as the above would mean the object have to be extracted from the list, even though a single object could've been returned instead.
Stick to best practises and export a list
Make a second endpoind /car/ and use the query parameters ?model=golf&year=2018, which are primarily used for filtering in a list, and have the result be a single object, as the singular endpoint states
The reason that I'm asking this is simply for the cleanness of the action: I'm 100% sure my GET request will result in single object, but still have to perform actions to extract it from the list. These steps should've been unnecessary. Aside of that, In my case I don't know the unique identifier, so cars/123 for retrieving a specific car isn't an option. I know, however, filters that will result in one object and one specific object altogether. The additional steps simply feel redundant.
1: https://learn.microsoft.com/en-us/azure/architecture/best-practices/api-design
2: https://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/
3: https://medium.com/hashmapinc/rest-good-practices-for-api-design-881439796dc9
As you've specifically asked for best practices in regards to REST:
REST doesn't care how you specify your URIs or that semantically meaningful tokens are used inside the URI at all. Further, a client should never expect a certain URI to return a certain type but instead rely on content-type negotiation to tell the server all of the capabilities the client supports.
You should furthermore not think of REST in terms of object orientation but more in terms of affordance and statemachines where a client get served every information needed in order to make an educated decision on what to do next.
The best sample to give here is probably to take a close look at the Web and how it's done for HTML pages. How can you filter for a specific car and how it will be presented to you? The same concepts that are used in the Web also apply to REST as both use the same interaction model. In regards to your car sample, the API should initially return some control-structures that teach a client how a request needs to be formed and what options could be filtered for. In HTML this is done via forms. For non-HTML based REST APIs dedicated media-types should be defined that translate the same approach to non-HTML structures. On sending the request to the server, your client would include all of the supported media-types it supports in an Accept HTTP header, which informs the server about the capabilities of the client. Media-types are just human-readable specification on how to process payloads of such types. Such specifications may include hints on type information a link relation might return. In order to gain wide-usage of media-types they should be defined as generic as possible. Instead of defining a media-type specific for a car, which is possible, it probably would be more convenient to use an existing or define a new general data-container format (similar to HTML).
All of the steps mentioned here should help you to design and implement an API that is free to evolve without having to risk to break clients, that furthermore is also scalable and minimizes interoperability concerns.
Unfortunately your question targets something totally different IMO, something more related to RPC. You basically invoke a generic method via HTTP on an endpoint, similar like SOAP, RMI or CORBA work. Whether you respect the semantics of HTTP operations or not is only of sub-interest here. Even if you'd reached level 3 of the Richardson Maturity Model (RMM) it does not mean that you are compliant to REST. Your client might still break if the server changes anything within the response. The RMM further doesn't even consider media-types at all, hence I consider it as rather useless.
However, regardless if you use a (true) REST or RPC/CRUD client, if retrieving single items is your preference instead of feeding them into a collection you should consider to include the URI of the items of interest instead of its data directly into the collection, as Evert also has suggested. While most people seem to be concerned on server performance and round-trip-times, it actually is very elegant in terms of caching. Further certain link-relation names such as prefetch may inform the client that it may fetch the targets payload early as it is highly possible that it's content will be requested next. Through caching a request might not even have to be triggered or sent to the server for processing, which is probably the best performance gain you can achieve.
1) If you use query like cars/where... - use CARS
2) If you whant CAR - make method GetCarById
You might not get a perfect answer to this, because all are going to be a bit subjective and often in a different way.
My general thought about this is that every item in my system will have its own unique url, for example /cars/1234. That case is always singular.
But this specific item might appear as a member in collections and search results. When /cars/1234 apears in these, they will always appear as a list with 1 item (or 0 or more depending on the query).
I feel that this is ultimately the most predictable.
In my case though, if a car appears as a member of a search or colletion, it's 'true url' will still be displayed.

Standard for RESful service with differing models?

From the perspective of an MVC developer, the Model should only contain Properties relevant to the view. So what is the best practice for dealing with this RESTful service scenario?
Usage 1
The RESTful endpoint "my-application/items/" is used to QUERY for a list of items which are bound to a paged list view of the items. It may contain many properties, such as ItemId, ItemName, CreatedDate, ModifiedDate, etc. It may even be a paged result of data from the server (eg 10 records out of 1000).
Usage 2
In a different area of the application, I need a select box for these items. In this scenario, I just need ItemId and ItemName. All other properties are irrelevant.
Do I...
...swallow my MVC pride and just use a single bloated model and a
single RESTful endpoint?
...create different RESTful endpoints with some sort of naming standard?
...do something else?
To me, this is not a theoretical REST issue. This is an implementation issue. Basically, you are asking whether you should implement a different endpoint for a separate use case or not. I agree with you when you say that the information exchanged with the client should be the minimum for performing a specific task. The only reason not to do so is convenience or budget.
In the use case 1, you should provide a wide set of data, in use case 2 you need far less of them..
Maybe use an endpoint as such .../items/details for the use case 1 and another endpoint .../items for the use case 2.
Maybe you could also implement a single endpoint and use a query parameter as such
.../items?detailed=true
Both solutions are perfectly acceptable.
The theoretical explanation behind this consideration is that REST asks the server to exchange resources' representation with the client. Representation means something similar to the view concept of the MVC model: it's not the entity itself, it's the most convenient way of describing it in a given context.
And this also means that different contexts may require different representations.

Designing REST api for returning count of multiple objects

I have a question on how should I design my rest api(s) given that I need to return count of different objects in my application. There are multiple approaches that could be thought off
Defining a single api that generally accepts the object identifier in the request body (json) and returns back the count for each of the object identifiers in the response. The drawback is the api is too generic and possibly not restful since there is no resource. The url would look like GET /counts
Define individual api's for each of the resources for which count is needed. Assuming I need to return counts for the fields defined in the software, tables, processes, tasks, jobs etc I would define individual api's for each of these resources. It would look like GET /field/count or GET /table/count. A side effect of this would be there would be many web api's for each of the resources we need the count for. Is that bad?
Kindly share your thoughts on the above approaches and any new ways in which I could design such an API that adheres to the REST standards.
Thanks
It totally depends on the client that is consuming the APIs.
Case 1. If its a WebApp which needs count of many tables on a single page then both will lead to bad design where you will have to make hundreds of calls just for counts data. You can club counts in a single API and send that as a response.
Case 2. If the client are individually using the count then i would recommend the 2nd approach where the resource is clearly defined. For the 2nd approach you are making the client intelligent which is not recommended.
As mentioned in the comments REST is a totally subjective topic so there can be multiple view points to every design.