Home »
AdonisJs
Creating a controller to handle CRUD endpoints in AdonisJs
Here, we are going to learn about the creating a controller to handle CRUD endpoints in AdonisJs?
Submitted by Radib Kar, on January 26, 2021
In our last tutorial, we created the endpoints for sending request for CRUD operation. Also, we have got the introduction to controllers & thus we know that to handle these requests we need to use route.js & a controller.
In this article, we will see how we can create a controller from scratch and what are the standard methods to handle requests?
Creating a resourceful controller
In past tutorials, we saw how to create a controller, but it created only a blank controller. In this tutorial, we will be creating a resourceful controller.
Run the below command,
adonis make:controller Project --resource
To create the boilerplate for project controller. Once the command is successfully created, you should see something like below:
'use strict'
/** @typedef {import('@adonisjs/framework/src/Request')} Request */
/** @typedef {import('@adonisjs/framework/src/Response')} Response */
/** @typedef {import('@adonisjs/framework/src/View')} View */
/**
* Resourceful controller for interacting with projects
*/
class ProjectController {
/**
* Show a list of all projects.
* GET projects
*
* @param {object} ctx
* @param {Request} ctx.request
* @param {Response} ctx.response
* @param {View} ctx.view
*/
async index ({ request, response, view }) {
}
/**
* Render a form to be used for creating a new project.
* GET projects/create
*
* @param {object} ctx
* @param {Request} ctx.request
* @param {Response} ctx.response
* @param {View} ctx.view
*/
async create ({ request, response, view }) {
}
/**
* Create/save a new project.
* POST projects
*
* @param {object} ctx
* @param {Request} ctx.request
* @param {Response} ctx.response
*/
async store ({ request, response }) {
}
/**
* Display a single project.
* GET projects/:id
*
* @param {object} ctx
* @param {Request} ctx.request
* @param {Response} ctx.response
* @param {View} ctx.view
*/
async show ({ params, request, response, view }) {
}
/**
* Render a form to update an existing project.
* GET projects/:id/edit
*
* @param {object} ctx
* @param {Request} ctx.request
* @param {Response} ctx.response
* @param {View} ctx.view
*/
async edit ({ params, request, response, view }) {
}
/**
* Update project details.
* PUT or PATCH projects/:id
*
* @param {object} ctx
* @param {Request} ctx.request
* @param {Response} ctx.response
*/
async update ({ params, request, response }) {
}
/**
* Delete a project with id.
* DELETE projects/:id
*
* @param {object} ctx
* @param {Request} ctx.request
* @param {Response} ctx.response
*/
async destroy ({ params, request, response }) {
}
}
module.exports = ProjectController
Well, so here you can see we have already had few functions by default as we have used the option --resource
Functions Used
So the functions are:
- index()
- create()
- store()
- show()
- edit()
- update()
- destroy()
But if you remember we created 5 endpoints, so obviously two functions are extra & we won't discuss those. Those two are create() & edit().
Now all the other functions are mapped to handle one of the five endpoints we created by convention.
Like,
- index() - function to handle GET projects request
- store() - function to handle PUT project request
- show() - function to handle GET project request
- update() - function to handle POST project request
- destroy() - function to handle DELETE project request
Let's first update the route.js file & then let send a simple response back to our postman to check whether our controllers are getting hit for appropriate requests or not.
route.js file
Please update the route.js file. If you have followed our tutorial you should be able to route the requests correctly. Below is the updated routings you should add in your route.js file.
Route.get('projects', 'ProjectController.index');
Route.put('projects', 'ProjectController.store');
Route.get('projects/:id', 'ProjectController.show');
Route.post('projects/:id', 'ProjectController.update');
Route.delete('projects/:id', 'ProjectController.destroy');
And in all the function send back a response with some message what you want. Like in the index() method I have added the response like below:
async index ({ request, response, view }) {
response.status(200).send({
message: 'index method is handling incoming request'
});
}
Similarly, add response messages with status code 200. Now let's test the endpoints and you should be getting the same response message back in postman.
Below are my testing results, you should also see a similar result if you have routed the endpoints correctly towards the controller functions.
Index() <---> GET projects
show() <---> GET project
store() <---> PUT projects
Now while sending the PUT request you might face something like below, that's because adonis disables such testings to add security since we haven't created this project as 'api only'. It was expected to get requests from the view part.
To overcome this,
You can see the shield.js file under config folder has the below snippet by default.
/*
|--------------------------------------------------------------------------
| CSRF Protection
|--------------------------------------------------------------------------
|
| CSRF Protection adds another layer of security by making sure, actionable
| routes does have a valid token to execute an action.
|
*/
csrf: {
enable: true,
methods: ['POST', 'PUT', 'DELETE'],
filterUris: [],
cookieOptions: {
httpOnly: false,
sameSite: true,
path: '/',
maxAge: 7200
}
}
}
So right now the CSRF protection is enabled, change this to enable: false to disable the protection,
update() <---> POST projects
destroy() <---> DELETE projects
One thing is you can also group the routings for a common collection. I would like to suggest you do that your own by checking out the Adonis doc page. Also, later we will cover that. From the next tutorial, we will be getting started with handling requests & communicating with the database with help of lucid query builders.