AdonisJS is a web development framework for Node.js that provides a solid structure and built-in tools to build robust and scalable web applications.
It is heavily inspired by other MVC frameworks, such as Laravel in the PHP world. AdonisJS is designed to simplify application development by offering a coherent architecture and ready-to-use tools.
AdonisJS focuses on improving our productivity and keeping our code organized. It provides a complete set of tools including an ORM (Object-Relational Mapper), a routing system, and a middleware layer, among others.
Some of the Main Features of AdonisJS,
- MVC Architecture: AdonisJS follows the Model-View-Controller (MVC) design pattern, which facilitates the separation of business logic, presentation, and data access.
- Integrated ORM: The ORM called Lucid helps us interact with databases easily, allowing us to work with data models without having to write SQL queries manually.
- Routing System: Its routing system allows defining routes intuitively and handling HTTP requests efficiently.
- Middleware: It allows us to implement functions that run before or after handling HTTP requests, useful for tasks like authentication and validation.
- CLI (Command Line Interface): AdonisJS includes a robust CLI to generate components, handle migrations, and perform other common development tasks.
These features allow us to handle common web development tasks without having to configure everything from scratch.
For more information about AdonisJS, we can consult the official AdonisJS documentation and explore the repository on GitHub to access the source code and additional examples.
Installing AdonisJS
To start working with AdonisJS, we first need to install it. We use npm
or yarn
to create an AdonisJS project.
npm init adonisjs@latest my-project
This command generates a base project structure with all the necessary configurations. Next, we access the project directory and run the server:
cd my-project
npm run dev
If everything works, you will see an “It Works!” on the screen (yes, nothing was killed, I could have put a logo or something but no! It Works)
Project Structure
Once a new project is created, AdonisJS provides a default directory and file structure to organize the application code. The file structure includes the following directories and files:
app
: This directory contains the application logic, including controllers, views, and models.config
: This directory contains the application’s configuration files.database
: This directory contains database migrations and seed files.public
: This directory contains public files like CSS, JS, and image files.resources
: This directory contains the application’s source files, such as views and style files.routes
: This directory contains the application’s routing files..env
: This file contains environment variables for the application.
How to Use AdonisJS
Let’s see how to start building a simple application with AdonisJS. We will create a small blog application with basic routes, controllers, and models.
Defining Routes
In AdonisJS, routes are defined in the start/routes.js
file. This is where we can specify how HTTP requests should be handled.
import router from '@adonisjs/core/services/router'
router.on('/').render('pages/home')
router.get('/hello-world', () => {
return 'Hello world from the home page.'
})
router.get('/posts/:id', ({ params }) => {
return `This is post with id ${params.id}`
})
Creating Controllers
Controllers handle the application’s logic for each route. We can create a controller using the AdonisJS CLI:
node ace make:controller PostController
The generated file is located at app/Controllers/Http/PostController.js
, and we can define the methods to handle our routes:
import type { HttpContext } from '@adonisjs/core/http'
export default class UsersController {
async index(ctx: HttpContext) {
return [
{
id: ctx.params.id,
username: 'virk',
},
{
id: 2,
username: 'romain',
},
]
}
async create({}: HttpContext) {}
async store({ request }: HttpContext) {}
async show({ params }: HttpContext) {}
async edit({ params }: HttpContext) {}
async update({ params, request }: HttpContext) {}
async destroy({ params }: HttpContext) {}
}
Now we can change the router to use our controller
router.get('/posts/:id', (ctx) => {
return new UsersController().index(ctx)
})
Creating Models
Models in AdonisJS represent tables in the database and allow us to interact with the data. We use the CLI to generate a model:
npm ace make:model Post
The generated file is located at app/Models/Post.js
and defines the schema of the model:
import { DateTime } from 'luxon'
import { BaseModel, column } from '@adonisjs/lucid/orm'
export default class Post extends BaseModel {
@column({ isPrimary: true })
declare id: number
@column.dateTime({ autoCreate: true })
declare createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
declare updatedAt: DateTime
}
To create the tables in the database, we use migrations. First, we generate a migration:
node ace make:migration posts
Then, we define the schema in the generated migration file located in database/migrations/
:
import { BaseSchema } from '@adonisjs/lucid/schema'
export default class extends BaseSchema {
protected tableName = 'posts'
async up() {
this.schema.createTable(this.tableName, (table) => {
table.increments('id')
table.timestamp('created_at')
table.timestamp('updated_at')
})
}
async down() {
this.schema.dropTable(this.tableName)
}
}
Finally, we run the migration to create the table:
node ace migration:run