Query string vs SQL Filter statement - rest

I am developing a rest-api.
My api maps a query string like: email=xyz#gmail.com&gender=MALE in a sql statement: where email = xyz#gmail.com.br and gender = MALE
So why not pass the SQL statament using just a POST method instead of a GET?
Is there any best practices?

Because that would not be REST, it would be something like SOAP.
REST is about resources and operations on them. If you implement REST using HTTP, there are HTTP verbs that should be used for specifict actions:
GET is for getting a resource
POST is for creating a new resource in a collection (plus some special cases
PUT is for changing an existing resource
DELETE is for deleting an existing resource
These verbs must follow a specific behaviour. One of these is that GET must not change the resource while POST usually does change it.
Using POST instead of GET is against REST and all established standards.
why not pass the SQL statament using just a POST
Because this would expose details about your implementation to the user. This can open security holes. REST is about resources, an abstraction, not about the easies way to expose a database.

Related

RESTFUL API: Using path parameters vs Query parameters

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

RESTful related resource using JSONAPI schema

I am following the jsonapi schema to return a standardised response from a web API. I want to reduce the number of HTTP requests to get related information so it looks like I want to use compound documents to return (for example) an article and two related comments.
I somewhat understand this but I am wondering what the RESTful GET request would be? I am thinking something like
http://api.mysite.com/v1/articles/1?comments=2
I like to be explicit but are the request parameters necessary in order to return related information from a resource?
Sound like you want /v1/articles/1?include=comments&limitComments=2
Where limitComments is an API-specific param (note member name requirements)
http://jsonapi.org/format/#query-parameters
http://jsonapi.org/format/#fetching-includes
Alternatively, you could /v1/comments?include=articles&filter[articles]=1&page[size]=2
See http://jsonapi.org/recommendations/#filtering
and http://jsonapi.org/format/#fetching-pagination

Upsert (update or insert) of resources with generated URIs in REST?

My data access layer supports the upsert operations (Spring Data's CrudRepository.save()), when the id field is not set a new record is inserted and when the id field is set it is updated.
I am wondering how to justify the additional effort required to create two separate REST methods (both on the backend and the frontend side):
POST /users, for creating a new user (and generating the URI of the newly created resource)
PUT /users/{id}, for updating the existing users
over creating just one REST method:
POST /users
Are there any benefits of having two seperate methods other than being more RESTful?
It's more clearer to using different resources for different actions.
By REST ideology - PUT Idempotent method and POST not Idempotent. So each POST request should return new item in response, but PUT should return the same item in response.
I think it's a good when behavior is expected.
But if you write documentation for your api, you can using one resource for both actions (but I would choose the first option).
The data access layer supporting upsert does not mean that the REST API should support it, too. I would not overload POST /users with two meanings. Stick to two different resources.
Edit:
POST /users has the general meaning of 'add a new instance to the resource collection'. I see no way to extend this to '... or update existing instance if an ID is given'. /users is the collection resource, not a single resource you want to manipulate. Doing a POST to a collection resource should manipulate the collection, not a single existing resource.

Modify Rest POST request behavior with query String

I have a resource which basically represents a number. I have two possible updates for this number: Set the number to a specific value or add a value to it. Now I'm confused if I can use the query string part of the URL to specify the desired behavior.
Something like this:
/resource/{id}/?mode=add
/resource/{id}/?mode=set
Or is there an alternative way two represent to update strategies for a rest resource?
An Alternative would be to extend the request body with this information but this since strange, since the request data should contain the data and not "meta information" for the request itself - as far as I understand REST apis.
The project is an ordinary angularjs (client) and java (server) project.

REST complex web request with GET

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.