推荐一个NodeJS 框架 AdonisJS

它是一个 服务端渲染 的 MVC 框架。如果熟悉 Laravel 框架(PHP 框架),你会发现这是 Laravel 的一个 NodeJS 版本。如果你熟悉Laravel PHP框架的话,上手AdonisJS 就很容易了。它是Laravel的缩小版。

AdonisJS 文档 暂时没得中文文档

项目的结构

Http Server

Http Request

  • AdonisJS 中,为了方便接收 HTTP 请求信息,所有的控制器方法和路由器闭包都会接收一个 Request 实例 。请看一下简单示例:
// 路由闭包中调用 request ,response
const Route = use('Route')

Route.get('post', function * (request, response) {
  const body = request.all()
   
  // cherry picking fields
  const body = request.only('title', 'description', 'categories')
})
// 控制器中调用 request, response
class IndexController {
  * index(requset, response) {
    // ...
  }
}
  • request.all() :包括所有查询字符串和请求体:
const data = request.all()
// example.html?id=1&name=John 
// <input name="gender" value="male" />
// => {"id":1, "name": "John", "gender": "male" }
  • request.only():跟 request.all() 类似,但是只包含定义的 key 值:
const data = request.only('name', 'email', 'age')
/* returns
{
  'name': '..',
  'email':'..',
  'age':'..'
}
*/
  • request.input(key,[defaultValue]):返回 input 标签对应的键值对,如果 value 为空,则返回 defaultValue:
const name = request.input('name')
const subscribe = request.input('subscribe', 'yes')
  • request.url() :获取请求的 URL(出去查询字符串):
// url - http://foo.com/users?orderBy=desc&limit=10
request.url()
// returns - http://foo.com/users
  • request.param(key, [defaultValue]) :返回查询字符串:
// url - http://foo.com/users?orderBy=desc&limit=10
request.param('orderBy')
// returns - desc

// 返回所有的查询字符串
request.params()
  • request.collect(key1, key2, ...):转化数据格式,直接看下面例子:
<form method="POST" action="/users">
  <div class="row">
    <h2> User 1 </h2>
    <input type="email" name="email[]" />
    <input type="password" name="password[]" />
  </div>

  <div class="row">
    <h2> User 2 </h2>
    <input type="email" name="email[]" />
    <input type="password" name="password[]" />
  </div>

  <button type="submit"> Create Users </button>
</form>
request.only('email', 'password', )
/* returns 
{
  email: ['bar@foo.com', 'baz@foo.com'],
  password: ['secret', 'secret1']
}
*/
request.collect('email', 'password')
/* returns
[
  {
    email: 'bar@foo.com',
    password: 'secret'
  },
  {
    email: 'baz@foo.com',
    password: 'secret1'
  }
]
*/

Http Response

为了方便尽快响应 HTTP 请求,AdonisJS 提供了 response 类给我们使用。可用于渲染 nunjucks views 或者格式化数据。以下是简单的示例代码:

// Render Views
Route
  .get('/', function *() {
    yield response.sendView('welcome')    // resources/views/welcome.njk
})
// JSON Response
Route
  .get('user', function * () {
    const user = yield User.all()    // fetch users
    response.json(users)
})
  • 常用的还有重定向(Redirects)
response.location('/signup')
// or
response.location('back')

Http Middleware

中间件的使用十分常见,比如验证用户是否登录。在 AdonisJS 中,中间件放在 app/Http/Middleware 文件夹下,以下是简单示例:

'use strict'

const geoip = use('geoip-lite')  // npm module

class CountryDetector {
  
  * handle (request, response, next) {
    const ip = request.ip()
    request.country = geoip.lookup(ip).country
    yield next    // 如果想要把 req, res 传递给下个中间件或者路由行为,注意使用 yield next 
  }
}

MVC 设计模式

整个架构的数据流程如果下图所示:

Model

Model 是从数据库(AdonisJS 使用的是 SQL)获取数据的数据层,为了使获取数据的过程简单和安全,Adonis 使用了很好的 ORM 架构(Lucid

Controller

控制器主要控制 HTTP 请求数据流,利用 Model 获取必要的数据(不仅数据库,第三方服务器的数据等都在控制器里边处理),并把获取的数据传递给 View 去渲染 HTML 页面。

// 引入依赖文件
const path = require('path')

// 定义控制器
class UsersController {

  // 依赖注入
  static get inject () {
    return ['App/Model/User']   
  }

  // 以参数形式接收依赖注入
  constructor (User) { 
    this.User = User 
  }
  
  // 自定义数据处理方法
  static _processUserInfo() {
    // ...
  }
  
  // 异步调用的方法
  * index () {
    const users = yield this.User.all()
    // 传递数据给视图渲染
    yield response.sendView('users',{
        userName,
        userInfo
    })
  }

}

module.exports = UserController

View

View 是整个 MVC 模式数据流的最后部分,主要是利用动态的数据(Nunjuck Template)去渲染(jinja 引擎) HTML 页面。
正如前边的数据流图所述,View 便是整个数据流程的末端,即利用前边步骤传来的数据进行页面渲染。AdonisJS 的视图引擎是建立在 nunjucks 的基础上的,所以 nunjucks 有的模板语法,在 AdonisJS 中一样可以使用。另外,AdonisJS 也提供了一些特有的 过滤器(filter)。

// Route
const Route = use('Route')
Route.get('/greet/:user', 'UserController.greet')
// Controller
class UserController {
  * greet (request, response) {
     const user = request.param('user')  // user: "John"
     yield response.sendView('greet', {user})
  }
}
// View
<h2>Hello {{ user }}</h2>    // <h2>John</h2>

Http Rounting

  • 路由部分的代码书写在 app/Http/routes.js 中,简单的例子如下
const Route = use('Route')    // 类似 include,跟 require 不同

Route.get('/', function * (request, response) {
    yield response.sendView('home')    // 这里使用 ES6 generator 语法达到异步请求数据的效果
})
  • 路由参数:路由参数是 URL 中的动态数据段,我们可以通过自定义的 URL 接受动态数据。如下例子:
Route.get('users/:id', function * (request, response) {
    const id = request.param('id')
    response.send('Profile for user with id ${id}')
})
  • 路由群:通常,会存在一系列路由共享同一个模块的情况,这就可能有时候需要修改这个模块的一些共同参数,我们把这些路由“集合”到一起,就方便修改了。例如下面的例子:
Route.group('version1', function () {
    Route.get('users', function * (request, response) {  // 路由是 /api/v1/users
        // ...
    })
}).prefix('api/v1').middleware('auth')    // 该路由群都会加上 api/v1 的前缀,并经过用户登录中间件的检验
  • 路由命名:书写完整的路径有时过于麻烦,为方便使用可以给路由命名。如下例子:
Route
    .get('users/:id', '与否.show')
    .as('profile') 

IoC Container 依赖注入 & Service Providers 服务依赖注入

Ioc Container 主要概念就是在容器内存储/绑定依赖关系,然后从容器中取回它们,而不是手动请求它们

  • IoC Container 绑定依赖关系示例代码如下:
const Ioc = require('adonis-fold').Ioc
const bugsnag = require('bugsnag')

Ioc.bind('Adonis/Src/Bugsnag', function (app) { 

  const Config = app.use('Adonis/Src/Config') 
  const bugSnagConfig = Config.get('services.bugsnag') 

  bugsnag.register(bugSnagConfig.apiKey, bugSnagConfig.options) 
  return bugsnag 

})
  • 绑定 Service Provider 的示例代码如下:
const ServiceProvider = require('adonis-fold').ServiceProvider

class BugSnagProvider extends ServiceProvider {

  * register () { 
    this.app.bind('Adonis/Addons/BugSnag', (app) => {
      const BugSnag = require('./BugSnag')
      const Config = app.use('Adonis/Src/Config')
      return new BugSnag(Config)
    })
  }

  * boot () { 
    // Everything is registered do some hard work
  }

}
原文地址:https://www.cnblogs.com/boyGdm/p/15593222.html