AdonisJSの紹介
MVCに則ったJavaScriptのフレームワークです
PHPのフレームワークの1つLaravelにめっちゃそっくりです
こちらを紹介する目的:JavaScripter人口増えたらいいな
PHPerがNode.jsに入る時にexpressだと取っつきにくいと思うんです
自分はめっちゃ苦労しました
それに比べたらAdonisJSはMVCなのでめっちゃ取っつきやすいと思います
Ruby on Rails使っている人にとっても学びやすいフレームワークかなと思います
そこでLaravelにそっくりということでLaravelのチュートリアルをAdonisJSでやってみます
基本のタスクリスト 5.1 Laravel
では早速
(AdonisJSのversionは4.1です)
// validateファイルの作成
npm i --global @adonisjs/cli
// プロジェクト作成
adonis new laravel-tutorial
ディレクトリ構造です
migrationsがあったりroutes.jsがあったりでLaravel使いには馴染みのある構成ですね!

// devサーバー立ち上げ
cd laravel-tutorial adonis serve --dev
動作確認 localhost:3333にアクセス

今回は簡単のためdatabaseにsqlite3を使います
// sqlite3を追加
yarn add sqlite3
早速tasksテーブルを作ります
// tasksテーブルのマイグレーションファイル作成
adonis make:migration tasks // 上記のコマンドのあと、「Choose an action Create table」この選択肢を選んでください
出来上がったmigrationファイル修正
upやdownの書き方もLaravelおなじみですね
'use strict'
/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')
class TasksSchema extends Schema {
up () {
this.create('tasks', (table) => {
table.increments()
table.string('name') // この1文をを追記
table.timestamps()
})
}
down () {
this.drop('tasks')
}
}
module.exports = TasksSchema
// migration実行
adonis migration:run
// Taskモデルの作成
adonis make:model Task
下記の内容のmdoelクラスが作られる
// app/Models/Task.js
'use strict'
/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
const Model = use('Model')
class Task extends Model {
}
module.exports = Task
次にルーティングの設定
// start/routes.js
'use strict';
const Route = use('Route');
const Task = use('App/Models/Task');
Route.get('/', async ({ view }) => {
const tasks = await Task.all();
console.log('tasks', tasks.toJSON())
return view.render('tasks', { tasks: tasks.toJSON() });
});
Route.post('/task', async ({request, response}) => {
await Task.create(request.only(['name']));
return response.redirect('/');
}).validator('Task'); // 後述するvalidatorを指定する
Route.delete('/task/:id', async ({params, response}) => {
const task = await Task.find(params.id);
await task.delete();
return response.redirect('/');
});
次はview
AdonisJSはedgeテンプレートを採用しています
これもまたLaravelのbladeファイルの記法とそっくり
レイアウトファイルから作ります
// view/layouts/app.edge
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Laravel Tutorial with AdonisJs</title>
// bootstrapをcdnで読み込む
{{ style('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u') }}
</head>
<body>
<div class="container">
<nav class="navbar navbar-default">
</nav>
</div>
@!section('content') // section前の! を忘れないで
</body>
</html>さらにtask.edge
// resources/views/task.edge
@layout('layouts.app') //レイアウトファイルを指定
@section('content') // レイアウトファイルの@!section('content')に埋め込まれる
<div class="panel-body">
@include('common.errors') // partialファイル(resources/views/common.errors)を読み込む
<form action="/task" method="POST" class="form-horizontal">
{{ csrfField() }} // CSRF「トークン」を生成
<div class="form-group">
<label for="task" class="col-sm-3 control-label">Task</label>
<div class="col-sm-6">
<input type="text" name="name" id="task" class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button class="btn btn-default">
<i class="fa fa-plus"></i> タスク追加
</button>
</div>
</div>
</form>
</div>
@if(tasks.length > 0)
<div class="panel panel-default">
<div class="panle-heading">
現在のタスク
</div>
<div class="panel-body">
<div class="table table-striped task-table">
<thead>
<th>Task</th>
<th> </th>
</thead>
<tbody>
@each(task in tasks) // tasksを一覧表示するためのループ
<tr>
<td class="table-text">
<div>{{ task.name }}</div> // taskの名前を表示
</td>
<td>
// deleteメソッドにするときはactionの末尾に_method=DELETEをつける
<form action="/task/{{task.id}}?_method=DELETE" method="POST">
{{ csrfField() }}
<button>タスク削除</button>
</form>
</td>
</tr>
@endeach
</tbody>
</div>
</div>
</div>
@endif
@endsection// resources/views/common/errors.jsの作成
@if(hasErrorFor('name')) nameをkeyにするflashメッセージがあるか確認
<div>
<strong>おや?何かがおかしいようです!</strong>
<br><br>
<p>{{ getErrorFor('name') }}</p> // あれば表示
</div>
@endif最後にバリデーション
バリデーションは別途設定する必要があります
// validationの追加
adonis install @adonisjs/validator
// start/app.jsの修正してバリデーションを使えるようにする
const providers = [ '@adonisjs/framework/providers/AppProvider', '@adonisjs/framework/providers/ViewProvider', '@adonisjs/lucid/providers/LucidProvider', '@adonisjs/bodyparser/providers/BodyParserProvider', '@adonisjs/cors/providers/CorsProvider', '@adonisjs/shield/providers/ShieldProvider', '@adonisjs/session/providers/SessionProvider', '@adonisjs/auth/providers/AuthProvider', '@adonisjs/validator/providers/ValidatorProvider' // ここを追加してください ]
// validateファイルの作成
adonis make:validator Task
// app/Validators/Task.js
'use strict'
class Task {
// バリデーションのルールを決める
get rules () {
return {
name: 'required|max:30'
}
}
// エラーメッセージの設定
get messages() {
return {
'required': '{{ field }} is required.',
'max': 'max 30 characters'
}
}
// sessionにエラーメッセージを設定
async fails(error) {
this.ctx.session.withErrors(error)
.flashAll();
return this.ctx.response.redirect('back');
}
}
module.exports = Task
実際のコードを下記のリポジトリに置いています
github.com
このチュートリアルではcontrollerなども利用していないのですが、
AdonisJSにもちゃんとcontrollerがあります
他にもIOCなど類似の機能はあるのでぜひ公式リファレンスをご覧ください
個人的にはAdonisJSはバックエンドのapiサーバーをして利用する際に力を発揮すると考えます
expressに比べcorsなど設定が楽だと思います(個人比)
(adonis newする際にapiモードを指定すればviewが作成されなくなります)
またapiの方も紹介しようと思います