I'm following some Azure Function tutorials on creating a REST API, this all seems straight forward. However I'm struggling to understand how I should deal with the different verbs.
Is the recommended practice to create a separate Azure Function for each verb? And then also separate functions for each variation of routing for each verb, so a e.g. a separete function for each of:
products/{productid} (GET)
products (GET, returns list)
products/me (GET returns a list of products belonging to the user making the request)
It seems to me I'm going to end up with a lot of Azure functions here. In the WebAPI approach I would have put all these in a single controller and the attribute routing would have taken care of the rest.
Is there another way to achieve this with Azure function?
You can use Azure Function Proxies to setup routing for HTTP verbs and parameters and then pass the call down to a single function. Creating a function per each verb/parameter combination seems to be an overkill.
Of course, if processing logic is completely different e.g. for GET vs POST, it makes sense to put those into separate functions. So, in the end it's your call, but you have tools for both scenarios.
Related
First, I do know path parameters need to be used when you are pointing at a resource and query parameters are meant to be used when you define something that can add a "property" (or change in time).
However, let's assume i need to get data belong to a user.
In this case, I am a fan of writing the REST API URL like this.
https://mylink/user/getbyid
AND not
https://mylink/user/get
In the way I write the REST API, i will call the URL like /user/getbyid?id=1. In the way I DO NOT write the API, you will call it /user/get/1.
Since I write my API calls like /user/getbyid, /user/getbyname, /user/getbyuid I rarely use Path parameters. 99% of the time i am using Query parameters.
Considering the way I write my api calls, am I going against the best practices? Or what I do is right or ignorable?
I do know path parameters need to be used when you are pointing at a resource and query parameters are meant to be used when you define something that can add a "property" (or change in time).
That's not actually right - you are welcome to encode information into either the path or the query as you prefer; the machines don't care, as long as your identifiers are consistent with the production rules defined in RFC 3986.
The "resource identifier" includes both the path and the query_part.
Since I write my API calls like /user/getbyid, /user/getbyname, /user/getbyuid I rarely use Path parameters. 99% of the time i am using Query parameters.
Yup, that's fine.
Considering the way I write my api calls, am I going against the best practices? Or what I do is right or ignorable?
Ignorable, I'd say. Resource identifiers are a lot like variable names; people can spend hours arguing about variable names, and the machines don't care. The same is true of resource identifiers.
Could these identifiers be improved? I think so; the key idea being that we're identifying a resource, rather than identifying the implementation details of how the resource is implemented. The identifier is, in a sense, the "name of the document".
Removing the getby... path segment would also be fine.
/users?id=1
/users?name=bob
/users?uuid=469149ae-ecc6-4652-b094-17c211ff58ef
... but, depending on your routing implementation, disambiguating those three resources might be clumsy. Adding additional path segments to make the routing easier is fine.
The best practices to design a REST API to perform the basic CRUD (Create, Read, Update, Delete) operations, use a combination of HTTP methods GET POST PUT PATCH DELETE, URL and/or parameter(s).
Assuming you want to design a REST API to perform CRUD operation for User
1. Create
To perform create, design an endpoint /users with POST http method.
# http method URL parameters
POST https://<yourdomain>/users, { first_name: "Peak", last_name: "Gen"}
2. Read
To perform Read, design an endpoint /users/<id> with GET http method.
# http method URL parameters
GET https://<yourdomain>/users/1
2. Update
To perform Update, design an endpoint /users/<id> with PUT or PATCH http method.
# http method URL parameters
PUT https://<yourdomain>/users/1, { first_name: "Nitin", last_name: "Sri"}
2. DELETE
To perform Delete, design an endpoint /users/<id> with DELETE http method.
# http method URL parameters
DELETE https://<yourdomain>/users/1
If you notice, the same URL is being used in Read, Update and Delete while their HTTP methods are different. Means the same URL routes to different actions based on their HTTP methods.
Read more about REST API
I really like the way Spring cloud function decouples the business logic from the runtime target (local or cloud) and makes it easy to integrate with serverless providers.
I plan to use SCF with AWS Lambda behind an API gateway to design the backend of a system.
However, I am not completely clear on what is the recommended way to handle REST related parameters such as Query params, headers, path etc. inside the Spring cloud functions.
As per our initial analysis, we could derive two possible approaches:
When enabling “Lambda proxy integration” in API Gateway, Query params and other information are available as Message headers inside the SCF.
We can use “Mapping templates” in API Gateway to map all the required information into a JSON body and deserialize as a POJO to take input directly into the SCF.
This way, the SCF does not need to bother about how the required data is passed to the API.
What is the recommended way to achieve this? Are we missing something that enables to do this in a better way?
I don't think you are missing anything featurewise, except perhaps that it might also be convenient to work with composite functions - e.g. marshal|transform, where marshal is a Function<Message<?>, ?> and transform is the business logic. The marshal function could be generic (and convert to some sort of canonical form), and be provided as an autoconfiguration in a shared library (for instance).
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.
I am working on a REST service and so far all the queries are retrieved using a GET request.
Right now we are using a sort of routing rule like this one:
API/Person/{id} GET
http://api.com/person/1
Now, what if I want to ask to the REST API "Give me a Person with FisrtName = 'Pippo'"
I have a complex DTO that I called PersonQueryDTO that can be sent to the REST method to interview the database using the query criterias.
Is this a good way to do it or should I build complex queries in a different way?
For me it's important to keep the REST principles.
If you want to stick with REST principles, then the way to do something like that is to supply additional parameters in the URL e.g.
GET API/Person?FirstName=SomeName
REST is all about identifying resources, API/Person identifies your collection of Person and the additional parameters are nothing but meta data which the service can use internally to determine what sort of result to return.
I have the basics of a REST service done, with "standard" list and GET/POST/PUT/DELETE verbs implemented around my nouns.
However, the client base I'm working with also wants to have more powerful operations. I'm using Mongo DB on the back-end, and it'd be easy to expose an "update" operation. This page describes how Mongo can do updates.
It'd be easy to write a page that takes a couple of JSON/XML/whatever arguments for the "criteria" and the "objNew" parts of the Mongo update function. Maybe I make a page like http://myserver.com/collection/update that takes a POST (or PUT?) request, with a request body that contains that data. Scrub the input for malicious querying and to enforce security, and we're done. Piece of cake.
My question is: what's the "best" way to expose this in a RESTful manner? Obviously, the approach I described above isn't kosher because "update" isn't a noun. This sort of thing seems much more suitable for a SOAP/RPC method, but the rest of the service is already using REST over HTTP, and I don't want users to have to make two different types of calls.
Thoughts?
Typically, I would handle this as:
url/collection
url/collection/item
GET collection: Returns a representation of the collection resource
GET collection/item: Returns a representation of the item resource
(optional URI params for content-types: json, xml, txt, etc)
POST collection/: Creates a new item (if via XML, I use XSD to validate)
PUT collection/item: Update an existing item
DELETE collection/item: Delete an existing item
Does that help?
Since as you're aware it isn't a good fit for REST, you're just going to have to do your best and invent a standard to make it work. Mongo's update functionality is so far removed from REST, I'd actually allow PUTs on the collection. Ignore the parameters in my examples, I haven't thought too hard about them.
PUT collection?set={field:value}
PUT collection?pop={field:1}
Or:
PUT collection/pop?field=1