JavaScript
Node.js
sails
Node.jsDay 7

Sails.jsでRailsチュートリアルをやってみる

最近、RailsライクなNode.jsのwebフレームワークとして、Sails.jsの存在を知りました。

折角なのでRailsチュートリアルの第2章をベースにモデルを作成する所までをやってみようと思います。

Sails.jsのインストール

$ yarn global add sails

プロジェクトの作成

localhost:1337にアクセスすれば、デフォルトのページが表示されます。

sails
$ sails new sails-tutorial
$ cd sails-tutorial
$ sails lift

=============================

rails
$ rails new rails-tutorial
$ cd rails-tutorial
$ rails server

「Hello, World!」を表示

コントローラーを生成

Railsの場合はプロジェクトの作成時にApplicationControllerが生成されますが、Sails.jsでは生成されないので、生成します。

sails
$ sails generate controller application hello

==========================

rails
$ sails generate controller application hello

「Hello, World!」を返す処理を実装

api/controllers/ApplicationController.js
/**
 * ApplicationController
 *
 * @description :: Server-side logic for managing applications
 * @help        :: See http://sailsjs.org/#!/documentation/concepts/Controllers
 */

module.exports = {
  /**
   * `ApplicationController.hello()`
   */
  hello: function (req, res) {
    return res.send('Hello, World!');
  }
};

==========================

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  def hello
    render html: "Hello, World!"
  end
end

ルーティングの設定

config/routes.js
module.exports = {
  '/': 'ApplicationController.hello'
}

==========================

config/routes.rb
Rails.application.routes.draw do
  root 'application#hello'
end

Usersリソースのマイグレーション

データベースの設定

RailsはデフォルトでSQLiteが使われますが、Sails.jsでは対応していません。
Sails.jsでは代わりにsails-diskを利用することで、ローカルにデータベースを構築することが出来ます。

因みに、Postgres,Oracle,MySQL,MongoDBなど主要なDBも普通に接続情報を記述すれば利用可能です。

config/connections.js
module.exports.connections = {
  // sails-disk is installed by default.
  localDiskDb: {
    adapter: 'sails-disk'
  }
};
config/models.js
module.exports.models = {
  connection: 'localDiskDb'
}

==========================

config/database.yml
default: &default
  adapter: sqlite3
  pool: 5
  timeout: 5000

development:
  <<: *default
  database: db/development.sqlite3

Usersモデルの生成

Sails.jsにはRailsのscaffoldのようなコマンドは存在しないので、モデルとコントローラーをそれぞれ生成します。
generate apiコマンドで両方のファイルを一度に生成可能ですが、空のモデルが作成されるだけなので、別々で生成しています。)

Sails.jsではモデルに対応する同名のコントローラーが存在すれば、自動でルーティングをしてくるようになります。

sails
$ sails generate model user name:string, email:string
info: Created a new model ("User") at api/models/User.js!

$ sails generate controller user
info: Created a new controller ("user") at api/controllers/UserController.js!

==========================

rails
$ rails generate scaffold User name:string email:string
      invoke  active_record
      create    db/migrate/20171206150716_create_users.rb
      create    app/models/user.rb
      ...

マイグレーションの実行

Sails.jsではsails liftの実行時に自動でマイグレーションが実行される(Production環境では自動で実行されない)ので、Railsのようにコマンドで実行することが出来ません。
細かくマイグレーションを管理したい場合は、sequelize/sequelize や tgriesser/knexなどの外部ツールを利用してください。

config/models.js
module.exports.models = {
  connection: 'localDiskDb',
  migrate: 'alter' // マイグレーションの起動設定をしておく必要がある
}

==========================

$ rails db:migrate

Usersリソースにアクセスする

Railsは画面ベースになるので省略します。

# ユーザーの生成
$ curl -X POST http://localhost:1337/user -d "name=太郎&email=tarou@tarou.com"
{
  "name": "太郎",
  "email": "tarou@tarou.com",
  "createdAt": "2017-12-06T16:30:04.224Z",
  "updatedAt": "2017-12-06T16:30:04.224Z",
  "id": 1
}%

# ユーザーの一覧を取得
$ curl localhost:1337/user
[
  {
    "name": "太郎",
    "email": "tarou@tarou.com",
    "createdAt": "2017-12-06T16:30:04.224Z",
    "updatedAt": "2017-12-06T16:30:04.224Z",
    "id": 1
  }
]%