javascript

NodeJS фреймворк с синтаксисом Laravel

 (и без лапши в коде)

  • суббота, 18 марта 2017 г. в 03:14:09
https://habrahabr.ru/post/324220/
  • Node.JS
  • Laravel
  • JavaScript


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


Многие из нас за достаточно короткое время привыкли к 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
  • И дружелюбное сообщество поддержки.

На этом я хочу звершить свой обзор и поделиться некоторыми ссылками: