Technology Blog

Look deep into latest news and innovations happening in the Tech industry with our highly informational blog.

AdonisJS: A full featured node framework for modern web servers

hkis

 

Node is becoming one of the most elected choices by developers for modern web servers. You can build web servers in various elegant ways, using up-to-date tools such as ExpressJS.

However, a lot of developers had a hard time to stick on a high level framework to build web servers for their applications, sticking with tools that will stay light but will require a lot of configuration and wiring to produce a complete setup for a large project.

we are going to focus on a higher-level framework that comes with batteries included, and that will allow you to implement advanced features easily.

AdonisJS

pic courtesy: blog.sourcerer.io

Meet AdonisJS

AdonisJS is a node framework inspired by the well-known Php framework Laravel. It relies on concepts such as dependency injection and service providers to make you design beautiful, reliable and easily testable code.

Get prepared to leave spaghetti code in favor of reusable OO structure.

Installation

First things first, to create a new AdonisJS server, you will need to install Adonis CLI, the command line tool that will help you manage your projects :

npm i -g @adonisjs/cli

This will provide you a “adonis” command to use in your terminal

To create a new adonis application, use the subcommand “new” :

adonis new my-adonis-server

As explained in the log, is uses the default fullstack-app template (adonisjs/adonis-fullstack-app), to create your project in a “my-adonis-server” folder.
You can now go to this folder and start serving your app in development mode :

cd my-adonis-server
adonis serve --dev

Your app is now served from your machine, you can now dive into your project !

Keep the server running for the rest of the introduction.

AdonisJS

pic courtesy: blog.sourcerer.io

A bit of modeling

Let’s now create one API to manage a resource. In the following chapter, we will create an endpoint to manage tasks.
First, let’s setup the project so it uses sqlite :

adonis install sqlite3

Then create the Task SQL table :

adonis make:migration tasks
# select "create table"
adonis migration:run

Note that every time you want to edit your database, you will have to create a migration.

Migrations will allow you to save every modification you are doing to your models, and will update data to follow the new formats and rules you are implementing.
It is possible to define a “up” method, and a “down” method, depending if you want to switch to go to a newer or older version.

Then, create the model and controller related to this table :

adonis make:model Task
adonis make:controller TaskController
# select "For HTTP requests"

You now have set up you database, created a table, a model, and a controller. The source code for the model and the controller is present on the app folder.

AdonisJSimage

pic courtesy: blog.sourcerer.io

You might have noticed that as you entered the last commands, the server automatically detected that your project changed, and took care of reloading the new setup.
Now we can add some content to our model. By creating another migration.

adonis make:migration tasks

Now edit the new file under database/migrations

'use strict'
const Schema = use('Schema')
class TasksSchema extends Schema {
  up () {
    this.table('tasks', (table) => {
      // alter table
      table.string('title')
      table.string('description')
      table.boolean('done')
    })
  }
  down () {
    this.table('tasks', (table) => {
      // reverse alternations
    })
  }
}
module.exports = TasksSchema

And run this migration

adonis migration:run

Now, you tasks models have a title, description, and done properties.

Creating a page displaying content

Now let’s create a page that displays a list of tasks.

//Route.on('/').render('welcome')
Route.get('/', 'TaskController.home')

Then, on your TaskController, add the code handling the “/” route.

'use strict'
const Task = use('App/Models/Task')
class TaskController {
    async home({view}) {
        // Fetch tasks
        const tasks = await Task.all()
        return view.render('tasklist', {
          tasks: tasks.toJSON()
        })
    }
}
module.exports = TaskController

And add the template of the page in “resources/views/tasklist.edge”

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Task list</title>
  {{ style('style') }}
</head>
<body>
  <section>
    <h1>Tasks</h1>
    @each(task in tasks)
      <div class="task">
        <h2>
          @if(task.done)
            <input type="checkbox" disabled checked />
          @else
            <input type="checkbox" disabled />
          @endif
          {{task.title}}
        </h2>
        <p>{{task.description}}</p>
      </div>
    </div>
    @endeach
  </section>
</body>
</html>

In the “public/style.css”, delete all the css rules, to put :

.task {
 border: 1px solid darkgrey;
 border-radius: 6px;
 background: lightgrey;
 margin: 10px;
 padding-left: 10px;
 padding-right: 10px;
} 

This will display an empty list of tasks on “localhost:3000/” (so basically, nothing at the moment !)
It is currently empty because there is no tasks at the moment on the database. Let’s fix this!

Creating tasks in your database

For the sake of this tutorial, we will create our first tasks on the TaskController method we already defined:

/* ... */
async home({view}) {
  // Fetch tasks
  const task1 = new Task
  task1.title = 'Walk the dog'
  task1.description = 'Go and walk for half an hour'
  task1.done = false
  const task2 = new Task
  task2.title = 'Feed the cat'
  task2.description = 'The food is on the fridge'
  task2.done = false
  const task3 = new Task
  task3.title = 'Buy some pizza'
  task3.description = 'Go at the shop before 7pm'
  task3.done = true
  await task1.save()
  await task2.save()
  await task3.save()
  const tasks = await Task.all()
  return view.render('tasklist', {
    tasks: tasks.toJSON()
  })
}
/* ... */

Load the tasklist once to insert your tasks in the database, then erase or comment those methods.

You should now see your tasks on the page.

Creating new tasks

Once this working, we would like to add new content via a new task form.

On your task controller, enter the task creation logic :

class TaskController {
  /* ... */
  async create({ request, response, session, auth}) {
    const taskPayload = request.all()
    const task = new Task
    task.title = taskPayload.title
    task.description = taskPayload.description
    task.done = false
    await task.save()
    session.flash({ message: 'Task created!' })
    return response.redirect('back')
  }
}

The task creation form in your tasklist template :

@if(flashMessage('message'))
  <span>{{ flashMessage('message') }}</span>
@endif
<form action="{{ route('TaskController.create') }}" method="POST">
  <input type="text" name="title" placeholder="title" />
  <input type="text" name="description" placeholder="description" />
  <button type="submit">Create task</button>
</form>
...

And the post route in “start/routes.js”

Route.post('/task/create', 'TaskController.create')

Now you can add tasks from the form displayed in your task list.

Deleting Tasks

To delete tasks, the implementation is pretty much the same as the one we did to create tasks :

  • Add a delete method in the controller
  • Adapt the template
  • Create the DELETE route

TaskController :

/* ... */
class TaskController {
  /* ... */
  async delete({ request, response, session, params}) {
    const task = await Task.find(params.id)
    await task.delete()
    session.flash({ taskHandling: 'Task deleted!'})
    return response.redirect('back')
  }
}

“resources/views/tasklist.edge”

...
<section>
 <h1>Tasks</h1>
 @each(task in tasks)
   <div class="task">
     <h2>
       @if(task.done)
         <input type="checkbox" disabled checked />
       @else
         <input type="checkbox" disabled />
       @endif
       {{task.title}}
     </h2>
     <a href="/task/delete/{{task.id}}">Delete</a>
     <p>{{task.description}}</p>
    </div>
  </div>
  @endeach
</section>
...

“start/routes.js”

 Route.get('/task/delete/:id', 'TaskController.delete') 

In this blog we have covered the basics of Adonis JS. If you really enjoyed reading it, please checkout our next blog in series to learn more about ‘Templating’, ‘Authentication’ and many more Adonis JS features.

Hire Node.js Developer from us, as we give you high quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“.

To develop the custom web app using Node.js, please visit our technology page.

Content Source:

  1. blog.sourcerer.io