AdonisJS Framework Tutorial: build a full-stack web application
Tags: javascript, webdev, tutorial, programming
Published: 2023-02-22 19:15:45

When it comes to web app development, there are dozens of frameworks to choose from. A less-known but well-loved framework is **AdonisJs**, known for its beautiful code and simplicity for the backend. 

AdonisJs is a Node. js MVC framework for consistent, stable, and expressive code. Adonis takes care of a lot of time-consuming development details by offering a **stable ecosystem** for server-side web applications. 

Developers who use Laravel note that AdonisJs offers the same pattern, design, coding structure, and command-based interface. It’s easy to learn AdonisJs and quickly get your application running. In this tutorial, we will introduce the framework and show you how to get started. 
 
**Today, we will learn:**
* [What is AdonisJs?](#what)
* [Adonis pros and cons](#pros)
* [Adonis folder structure](#folder)
* [Create a basic application](#create)
* [Parts of a Full-stack application with Adonis](#app)
* [What to learn next](#next)
 
<br>
 
<a name="what"></a>

## What is AdonisJs?

AdonisJs is a Node.js framework based on Laravel. It implements similar concepts of Dependency Injection and Providers, beautiful code, and an intuitive design. AdonisJs was designed to bring developers joy and ease in their work, which is why it flouts a consistent and expressive API for full-stack web application development. 

This Laravel-style MVC framework focuses on the central aspects of creating a scalable, stable and scalable web application, such as:
* Pleasant developer experience
* Consistent API
* Speed & productivity 
* Support for mailing, authentication, data validation, Redis, and more

<br>

<a name="pros"></a>
 
## AdonisJs Pros and Cons

Let’s take a look at the most notable pros and cons of AdonisJs. 
 
### Pros 

* **Folder structure:** AdonisJs offers a convenient folder structure that makes it easy to stay organized.
* **Validator:** AdonisJs provides a dedicated validation provider that makes validating user input easy
* **Lucid ORM:** AdonisJs has first-class support for databases like MariaDB and MySQL.
* **ICO and Service Provider:** AdonisJs offers an easy way to manage dependencies through IOC. Service providers can manage life-cycle dependencies. 
* **Security:** AdonisJs comes with tools to protect websites against common web attacks like cross-site forgery protection.
* **Testing:** AdonisJS eases the challenges of manual testing by enabling developers to write functional unit tests to test their web applications.

<br>

### Cons

* **Community:** Since AdonisJs is somewhat new and less popular, the community of users and support is small. This means that you’re less likely to find support if you get stuck. 
* **Documentation:** The documentation for AdonisJs is currently immature, meaning that some parts are incomplete. 
* **Plugins:** There are fewer plugins available for AdonisJs due to its popularity and age
* **Not “battle-tested”:** Since fewer large-scale websites are built with AdonisJs, it hasn’t been battle-tested for production compared to other frameworks. 

<br>

<a name="folder"></a>
 
## AdonisJs Folder Structure 
 
Now that we have a functioning application, let’s learn more about its file structure before we get started with our first application. AdonisJs has an MVC structure, which makes it easy to organize files. This structure allows us to stay organized and scale files later. 
 
> **Refresher:** The Model View Controller (MVC) architecture is made up of three parts:
>  
> 1. Model: The lowest level of the pattern for maintaining the data.
>
> 2. View: This enables the user to view the data.
>
> 3. Controller: The software code that controls the Model and View.
 
Let’s look into the AdonisJs folder structure and define some key terms. 

![AdonisJS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5fjooxfpyc75hrodmkg.png)

### App
 
The app folder contains the application logic, including:
* **Controllers:** These control the flow of logic. Controllers can be bound together with routes.
* **Middleware:** Middleware contains the methods to l be executed before or after an HTTP request.
* **Models:** These define the database models and relationships.

> More folders like Validators, Exceptions, Helpers, and ModelFilter can be created inside the app folder.

### Config
This is where our application configuration is stored. We can also create our config file here.

### database
We use this folder to store the migrations, seeds, and factories.

### public
This is where we put our static files, like images, CSS, and JavaScript files. They will be called directly over HTTP.

### resources
This is where we put the view templates and Edge template files.

### start
These files are used to load the application. This is also where we can create files such as Events, Redis, and Hooks.

### .env
The .env file is located at the root folder. It will contain all the variables related to our working environment. Development and production usually have different settings.

### ace
The ace file comes is used for executing project-specific commands.

### package.json
This is a standard Node.js file.

### server.js
This file bootstraps the HTTP server.

<a name="create"></a>
 
## Create a basic application
 
Now that we’re familiar with AdonisJs, let’s learn how to actually make our first application. It’s quite simple to get started. First, you must download AdonisJs from the official site, or you can follow along with Educative’s embedded coding widget for now. 
 
We’ll start with the `adonis` executable to create our first application. In this example, we will be making a blog application. 

```js
adonis new blog
```

This command creates a new project, called blog. Next, we will `cd` into the directory to start the server.

```js
cd blog
npm run dev
```
 
**Output:** 

```js
[nodemon] starting `node --harmony_proxies server.js`
info adonis:framework serving app on http://localhost:3333
```

<br>

### Creating Routes 
The `start/routes.js` file defines the URL patterns for users to access as entry points to the web application. When a user requests a URL, Adonis finds the URL pattern inside `start/routes.js`, so if the pattern matches, Adonis processes the logic inside that route. 

> We can bind routes with controllers as logic handlers and attach routes to middleware and validators. 

AdonisJs offers a default route that renders the `welcome.njk` view. To start from scratch, we must first remove this. Below, we implement code that registers 2 different routes for a home and contact page.
 
```js
'use strict'
 
const Route = use('Route')
 
Route.on('/').render('home')
Route.on('/contact').render('contact')
```
 
<br>

### Creating Controllers

Controllers handle application logic. They are associated with our models, views, and helpers. Controllers respond to HTTP requests, so they are not meant to be included in other files. 

> **Tip:** Try to refactor controllers into separate files to avoid messy code.

```js
'use strict'
 
class TestController {
 hello(){
   return 'Hello from Controller'
 }
}
 
module.exports = TestController
```
 
**Output:**

 “Hello from controller”
 
Inside the `app/Controllers/Http/TestController.js` file, we created a function called `hello()`. We access the controller on line 20. `TestController` is the controller’s name, and `hello` is the name of the method.

![AdonisJS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u318czzhmz63skjvmg2k.png)

<br>

### Creating Views
Views are the components visible to the user. Views are saved in the resources/views directory with a `.njk` extension. Below, we create two views for our pages from above. 

```js
./ace make:view home
./ace make:view contact
```

> Ace is a command line utility tool for Adonis used for making views, controllers, and models.

We can add to our views using HTML inside the files we create. In the example below, Bootstrap is used for design. 

```js
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/css/bootstrap.css">
  <link rel="stylesheet" href="/style.css">
</head>
<body>
  <div class="container">
 
    <div class="header clearfix">
      <nav>
        <ul class="nav nav-pills pull-xs-right">
          <li class="nav-item"><a href="/" class="nav-link">Home</a></li>
          <li class="nav-item"><a href="/about" class="nav-link">About</a></li>
          <li class="nav-item"><a href="/contact" class="nav-link">Contact</a></li>
        </ul>
        <h3 class="text-muted"> Adonis Blog </h3>
      </nav>
    </div>
 
    <section>
      {% block content %}{% endblock %}
    </section>
 
  </div>
</body>
</html>
```

From there, we can extend the base template to the other views and add CSS in the `public/style.css` file.

<br>


<a name="parts"></a>
 
## Parts of an AdonisJs Application

Now we know how to create a basic application, but there is still a lot to using Adonis. Let’s go over some of the other important terms you need to know. 

<br>

### Middleware
Middleware is a set of functions that run before or after an HTTP request hits the router. Middleware is separated into three types:
* **Server:** executes before a request hits the router system 
* **Global:** executes when a route pattern matches the URL request.
* **Named:** is attached to and executed for a specific route or route group
 
Middleware is created inside the folder `app/Middleware` and registered inside the `start/kernel.js` file.

![Middleware](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hqryz3i3j0e48bknyb3g.png)

We could, for example, create named authentication middleware so that only logged-in users can access the site.

```js
'use strict';
 
class AuthRequired {
 async handle ({ auth, response }, next) {
   try {
     await auth.check()
   } catch (error) {
     return response.json({
       error: "Unauthorized access"
     })
   }
   // call next() to advance the request
   await next()
 }
}
 
module.exports = AuthRequired;
```

<br>

### Request Methods 
The request object offers methods to get information about the request. We can create routes to URLs in the `start/route.js` file. AdonisJs creates a request object for any URL request with the global middleware. 

The global middleware completes this in the default `BodyParser`. There are many request methods. Below we named a few: 
* **`request.all()`**: Returns an object that contains all request data (including query params and request body data).
* **`request.get()`**: Returns an object that contains query params data.
* **`request.post()`**:
Returns an object containing request body data from the submitted form.
* **`request.input(key)`**: Returns the value of the specified key.

<br>

<a name="next"></a>

## What to learn next

Congrats! You should now have a good idea of what AdonisJs has to offer and how you can get started. There is still a lot to learn. Next, you should look into:
* Unit Testing with Adonis Vow
* Using hooks 
* Migrations and query builders
* Edge Templates

To get started with these concepts, check out Educative's course, **[Building Full-Stack Web Applications with AdonisJs](https://www.educative.io/courses/building-full-stack-web-applications-adonisjs?eid=5082902844932096)**. This course is a detailed guide to AdonisJs, covering all the fundamentals: routes, controllers, middleware, hooks, and more. 

By the end, you'll have tons of hands-on practice and will be able to confidently write your full-stack applications.

*Happy learning!*

### Continue reading about web applications on Educative
* [Ionic Framework Tutorial: Build your first cross-platform app](https://www.educative.io/blog/ionic-framework-tutorial?eid=5082902844932096)
* [How to Design a Web Application: Software Architecture 101
](https://www.educative.io/blog/how-to-design-a-web-application-software-architecture-101?eid=5082902844932096)
* [MVC Architecture in 5 minutes: a tutorial for beginners](https://www.educative.io/blog/mvc-tutorial?eid=5082902844932096)


### Start a discussion
What JS framework do you want to learn about next? Was this article helpful? Let us know in the comments below!