Пробежавшись по Хабру с удивлением заметил, что этот фреймворк упомянут только в нескольких дайджестах, хотя по моему мнению заслуживает большего внимания. Ниже будет много кода и совсем немного комментариев к нему. И да, друзья! Это моя первая статья на хабре, просьба сильно не быть и не ругать.
Многие из нас за достаточно короткое время привыкли к Laravel, его изящный стиль, Artisan для консоли, Eloquent ORM, Middlewares, Providers и т.д. Так подумал и создатель фреймворка Adonis JS и полностью повторил все то, за что мы любим laravel но только на NodeJS — ну разве это не прекрасно? Давайте посмотрим поближе:
Структура приложения
├── app
│ ├── Commands
│ ├── Http
│ ├── Listeners
│ ├── Model
├── bootstrap
├── config
├── database
│ ├── migrations
│ └── seeds
├── providers
├── public
├── resources
│ └── views
├── storage
Поддерживаемые базы данных
- PostgreSQL
- SQLite
- MySQL
- MariaDB
- Oracle
- MSSQL
Миграции и консольная утилита Ace (Artisan)
#выполним в консоли
./ace make:migration users --create=users
#откроем
database/migrations/1464437815620_users.js
Код миграции
'use strict'
const Schema = use('Schema')
class UsersSchema extends Schema {
up () {
this.create('users', (table) => {
table.increments()
table.string('email').unique()
table.timestamps()
})
}
down () {
this.drop('users')
}
}
module.exports = UsersSchema
Некоторые команды Ace
#запуск миграции
./ace migration:run
#статус миграций
./ace migration:status
#откатить последний шаг миграций
./ace migration:rollback
#сбросить и заново накатить миграции
./ace migration:refresh
Несколько интересных наблюдений
Установка AdonisJS достаточно быстрая и сводиться всего лишь к нескольким командам. После утсановки сразу же можно выкатить миграцию, по умолчанию фреймворк создаст SQLite файл в папке database.
Роутинг
const Route = use('Route')
const User = use('App/Model/User')
Route.get('/', function * (request, response) {
const users = yield User.all()
response.json(users)
})
Route.get('users', 'UsersController.index')
База данных
Работа с БД в AdonisJS также прекрасна как и в Laravel 5, есть Gettters | Setters, Database Hooks позволяющие прослушивать события моделей и например в момент Save выполнять некоторые действия.
Query Builder
const john = yield Database
.table('users')
.where('username', 'john')
.limit(1)
Lucid (Eloquent)
yield User.all()
yield User.query().where('status', 'active').fetch()
Relations
class User extends Lucid {
profile () {
return this.hasOne('App/Model/Profile')
}
posts () {
return this.hasMany('App/Model/Post')
}
}
А зачем AdonisJS если есть Laravel?
Несмотря на то что php активно развивается, js во многом обогнал его. Достаточно взглянуть на фронтенд и его фреймворки. Один VueJS чего стоит. Пробегусь по пунктам:
Один и тот же синтаксис
Похожие языковые конструкции как на фронте, так и на бэке
Гигантский мир npm
Вам нужен хитрый функцинал поищите его на npm он ни чуть не меньше composer.
Асинхронность из коробки
В контроллере можно вернуть response в самом начале. А все трудоемкие и блокирующие операции выполнять после этого, на фоне:
Высокая производительность
Я провел несколько своих маленьких тестов, и NodeJS их все выиграл.
WebSocket
Очень удобно работать с ws используя Eloquent-подобную модель.
class SiteController {
* save (request, response) {
response.ok({success:true})
const post = new SiteRequest()
post.fill(
request.all()
)
yield post.save() // SQL Update
console.log(request.all())
}
}
А как же быть с однопоточностью js?
Данный код это мое кастомное решение взятое из док NodeJS, позволяет распараллелить процессы:
const cluster = require('cluster');
const numCPUs = require('os').cpus().length
const http = require('./bootstrap/http')
if (process.env.NODE_ENV === 'production') {
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// Workers can share any TCP connection
// In this case it is an HTTP server
runServer()
console.log(`Worker ${process.pid} started`);
}
}else{
runServer()
}
function runServer() {
const http = require('./bootstrap/http')
http(function () {
use('Event').fire('Http.start')
})
}
Также есть
- Мультитранспортная работа с Email.
- Middlewares, для взаимодействия со входящими запросами HTTP.
- Nunjucks шаблонизатор.
- Поддержка событий всего приложения.
- Встроенная поддержка Redis.
- Безопасная загрузка файлов.
- Средства защиты с поддержкой CORS, CSRF
- И дружелюбное сообщество поддержки.
На этом я хочу звершить свой обзор и поделиться некоторыми ссылками:
- Документация AdonisJS
- NuxtJS + AdonisJS — Изоморфное SPA на VueJS + AdonisJS