javascript-adonisjs

Build Web Applications with AdonisJS

  • 5 min

AdonisJS is a web development framework for Node.js that provides us with a solid structure and integrated 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 that includes 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: 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 for generating components, handling migrations, and performing other common development tasks.

These features allow us to handle common web development tasks without having to configure everything from scratch.

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 navigate to 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, they haven’t bothered more, they 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 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 source files, such as views and style files.
  • routes: This directory contains the application 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’ll create a small blog application with basic routes, controllers, and models.

Define 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}`
})
Copied!

Create Controllers

Controllers handle the application logic for each route. We can create a controller using the AdonisJS CLI:

node ace makePostController

The generated file is located at app/Controllers/Http/PostController.js and we can define 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) {}
}
Copied!

Now we can change the router to use our controller

router.get('/posts/:id', (ctx) => {
  return new UsersController().index(ctx)
})
Copied!

Create Models

Models in AdonisJS represent tables in the database and allow us to interact with data. We use the CLI to generate a model:

npm ace makePost

The generated file is located at app/Models/Post.js and defines the model schema:

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
}
Copied!

To create the tables in the database, we use migrations. First, we generate a migration:

node ace makeposts

Then, we define the schema in the generated migration file 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)
  }
}
Copied!

Finally, we run the migration to create the table:

node ace migration