Пробежавшись по Хабру с удивлением заметил, что этот фреймворк упомянут только в нескольких дайджестах, хотя по моему мнению заслуживает большего внимания. Ниже будет много кода и совсем немного комментариев к нему. И да, друзья! Это моя первая статья на хабре, просьба сильно не быть и не ругать.
Многие из нас за достаточно короткое время привыкли к 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