I'm developing a REST Api using Node.js & Express.js. Recently I've started looking towards best practices for REST Api design but it's bit confusing so please bear with me.
For Example:
Lets say I have the following API Collections:
- Users
- Tasks (every task must belong to a User)
And Have these resources:
- GET
/api/users
returns all Users - GET
/api/users/:id
returns a specific User - POST
/api/users
will create a single User - POST
/api/users/:id
will update a specific User - POST
/api/tasks
will create a new Task but will assign it to the loggedIn User. - POST
/api/tasks/:id
will update a specific Task - GET
/api/tasks
will get all Tasks - GET
/api/users/:id/tasks
will get all Tasks for a specific User - GET
/api/users/:id/tasks/:id
will get a specific Task for a Specific User
Now each "Resource" above is redirected towards a "Controller" that actually performs actions.
For example:
POST ('/api/users', myController)
let myController = (req,res) => {
Create new User
Save to Database
Call Private Send an Email to Admin function etc
}
Questions:
Lets say I have to perform some queries on a resource such as filter
should I:
OPTION 1:
Create a new resource like so /api/users/:id/tasks/filter
and within my Controller and perform the filtering actions on the database within the controller
OPTION 2:
Use Query Strings like so /api/users/:id/tasks?filter=title::someValue&priority::someOtherValue
. According my knowledge doing this will NOT create a new resource but will simply call the /api/users/:id/tasks
resource with the above Query Strings.
If I follow OPTION 2 thats means I will only have one Controller that manages the /api/users/:id/tasks
actions so to handle any Queries for this Resource should I do the following:
GET ('/api/users/:id/tasks', myController)
let myController = (req,res) => {
if(req.filter)
{handle Query here and get data from database and return to user}
else if(some other query)
{handle query here}
else if(some other query)
{handle query here}
else {
if there are NO queries then get get all Tasks for a specific User.
}
}
Is the above implementation/concept correct? To me it seems messy and confusing. So what am I doing wrong here? What's the correct way of handling queries? Should a single Controller for a resource handle everything for that particular resource?
I'm having trouble thinking in "REST" there is so much information I'm not sure what right and whats wrong. So my basics are a bit weak so any guidance towards that would be very helpful (any articles or online resources).
/api/users/:id/tasks?title:someValue
why not do/api/users/:id/tasks/:title
. Complex query strings are a headache, but as Laiv points out this isn't really anything to do with REST and more just to do with how you implement a system that takes an arbitrary amount of parameters and performs an action. Keep the query string as simple as possible and use URLs for everything else