Node.js
WebAPI
loopback

Web API フレームワーク LoopBack で遊んでみる

More than 1 year has passed since last update.

LoopBack とは

LoopBackは Web API フレームワークです。

最近は、よりリッチなユーザ体験を提供するために、Web アプリケーションをSPA化する流れが強くあるなーと思います。
それと同時に、バックエンドとしての API サーバ構築の需要もすごく高まってきていて、LoopBack はその API の生成がとても簡単にできるフレームワークです。

Node.js 製なので、フロントエンドとバックエンドを JavaScript のみで記述できます。Universal Web App!
Express がベースになっているのですが、大きな特徴として、モデルが生成されると同時に RESTful な API を自動で生成してくれます。
モデルの生成もジェネレータが用意されているので、一行もコードを書かずに API サーバを構築できます。

LoopBack の特徴

公式ドキュメントに特徴が載っていたので、さらっと転載しておきます。

  • ほとんど、あるいは全くコードを書かずに、動的な end-to-end の REST APIs を作成できる
  • 主要なリレーショナル・データベース、MongoDB、SOAPやREST APIのデータにアクセスできる
  • モデル・リレーションシップと複雑なAPIへのアクセス制御を統合できる
  • モバイルアプリのための、プッシュ通知、Geolocation、ファイル管理が扱える
  • Android、iOS、JavaScript SDK のクライアントアプリを簡単に作ることができる
  • オンプレミスでもクラウドでも動かすことができる

他の Node.js フレームワークとの比較

LoopBack と他のフレームワークの比較です。公式の比較ページを参照しつつ、調べてみました。

LoopBack

  • API framework
  • StrongLoop社のAPIフレームワーク
  • ブラウザから閲覧可能なAPIエクスプローラや、コードジェネレータを標準搭載
  • Angular, Browser, Node.js, iOS, Android, Xamarin向けのクライアントサイド SDK がある
  • プッシュ通知、ファイルストレージ、サードパーティログイン、位置情報と連携可能

Express

  • HTTP server liblary
  • StrongLoop社のWebアプリケーションフレームワーク
  • 最も知名度が高く、情報量も多い
  • 機能はミドルウェアとして構築していく

Hapi

  • HTTP server framework
  • コードを設定ファイルのように記述させることが大きな特徴
  • 日本語の情報量は少ない

Sails

  • Web MVC framework
  • RailsライクでフルスタックなWebアプリケーションフレームワーク
  • 後から拡張していく思想の他のフレームワークとは異なり、単体で全部のせ
  • Railsに似たジェネレータでCRUDなコードの生成が可能

Meteor

  • Full-stack JavaScript app platform
  • SPA向けのフルスタックなWebアプリケーションフレームワーク
  • GithubのStar数ではExpressを超え、昨年あたりから注目されている
  • リアクティブアプリケーションを最小限のコードで構築可能
  • JavaScript, Cordova for iOS and Android, React, AngularJS向けのクライアントSDKがある

LoopBackと他のフレームワークとの大きな違いは、APIフレームワークとして特化している点と言えそうです。

DBや外部APIとの連携もアドオンが一通り揃っていますし、iOS / Android 向けの SDK もあるのでネイティブアプリ開発にも利用できます。
多少のロジックも Express と同じように書けそうです。

Sails や Meteor のようなフルスタックフレームワークにも同等の機能はありますが、API サーバに使うにはちょっと重すぎると思います。
ライトな API サーバを、スピーディに構築するにはとても良さそうな印象。

LoopBack で遊んでみる

さっそく、一通り LoopBack で遊んでみます。
分かりやすく、とても Minimal な Twitter の API を作ってみました。

インストール

$ sudo npm install -g strongloop

アプリケーションを作成

$ mkdir loopback-tutorial & cd loopback-tutorial
$ slc loopback

loopback-tutorial-01.png

アプリ名を聞かれるので、入力して Enter で進みます。
自動生成されるコードは下記の通り。

$ tree . -I node_modules
.
├── README.md
├── client
│   └── README.md
├── package.json
└── server
    ├── boot
    │   ├── authentication.js
    │   └── root.js
    ├── component-config.json
    ├── config.json
    ├── datasources.json
    ├── middleware.json
    ├── middleware.production.json
    ├── model-config.json
    └── server.js

アプリケーションを起動

$ node .

http://localhost:3000/にアクセスすると、以下のようなJSONが表示されました。

{"started":"2016-02-25T12:48:39.571Z","uptime":39.405}

http://localhost:3000/explorer/にアクセスすると、このような画面に。

loopback-tutorial-02.png

Userをクリックすると、既にAPIが作成されていることが分かります。

loopback-tutorial-03.png

モデルを作成

$ slc loopback:model
? Enter the model name: Tweet                             // モデル名
? Select the data-source to attach Tweet to: db (memory)  // データの保存場所
? Select model's base class PersistedModel                // どのクラスを継承するか
? Expose Tweet via the REST API? Yes                      // REST APIとして公開するか
? Custom plural form (used to build REST URL):            // モデル名の複数形
? Common model or server only? common                     // 共有か、サーバのみか
Let's add some Tweet properties now.

Enter an empty property name when done.
? Property name: body                         // プロパティ名
   invoke   loopback:property
? Property type: string                       // 型
? Required? Yes                               // 必須かどうか

Let's add another Tweet property.
Enter an empty property name when done.
? Property name:[Enter]

slc loopback:modelコマンドを終了すると、common ディレクトリが作られています。
React.js や Angular.js などと組み合わせて使う場合には、この common ディレクトリを共有します。

$ tree common
common
└── models
    ├── tweet.js
    └── tweet.json

common/models下には、tweet.jstweet.jsonが新しく生成されています。
tweet.jsonには、下記のようなスキーマ情報が格納されています。

common/models/tweet.json
{
  "name": "Tweet",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "body": {
      "type": "string",
      "required": true
    }
  },
  "validations": [],
  "relations": {},
  "acls": [],
  "methods": {}
}

もう一つのtweet.jsは、実装ファイルです。まだ実装は何もありません。

common/models/tweet.js
module.exports = function(Tweet) {

};

また、server/model-config.jsonの末尾に、モデルの情報が追加されています。

{
  ...
  "tweet": {
    "dataSource": "db",
    "public": true
  }
}

ちなみに、生成時に common ではなく server を選択すると、common/modelsではなくserver/modelsに生成されます。

http://localhost:3000/explorer/にアクセスすると、Tweet API が作られていることを確認できました。

loopback-tutorial-04.png

DB との連携

$ npm install loopback-connector-mysql --save

使い方は github 上の README に書いてありますが、とても簡単。

loopback-connector-mysqlパッケージをインストールしたら、package.jsonに依存関係のあるパッケージを追記して、npm installを実行します。

{
  ...
  "dependencies": {
    "loopback-datasource-juggler": "latest",
    "loopback-connector-mysql": "latest"
  }
}

あとは、server/datasources.jsonにDBの接続設定を書くだけとのこと。

    var DataSource = require('loopback-datasource-juggler').DataSource;
    var dataSource = new DataSource('mysql', {
        host: 'localhost',
        port: 3306,
        database: 'mydb',
        username: 'myuser',
        password: 'mypass'
    });

MySQL 以外にも、MongoDB / Oracle Database / PostgreSQL などに対応したコネクタが用意されているようです。
使用できるコネクタの一覧が下記に載っています。

Connecting models to data sources

モデルのリレーションを定義

$ slc loopback:relation
? Select the model to create the relationship from: Tweet  // リレーションを定義するモデル名
? Relation type: belongs to                                // リレーション定義
? Choose a model to create a relationship with: (other)    // どのモデルと関連付けるか
? Enter the model name: User                               // リレーション先のモデル名
? Enter the property name for the relation: user           // リレーション先のプロパティ名
? Optionally enter a custom foreign key:                   // カスタム外部キー

slc loopback:relationコマンドを実行すると、common/models/tweet.jsonにコードが追記されます。

  ...
  "relations": {
    "user": {
      "type": "belongsTo",
      "model": "User",
      "foreignKey": ""
    }
  },
  ...

あれ?

ここで問題が発生。User モデルにリレーションを定義したかったのですが、モデルの候補に表示されず。
新しく User モデルを作ろうとしても、デフォルトで作られているからか Validation error: invalid ModelDefinition - name: is not unique が表示されてしまいました…。

(解決法をご存知の方がいたら教えてください!)

もう一歩理解する

LoopBack がどのように動いているのかは、LoopBack core concepts にまとまっています。
一読してみてから、簡単なロジックを書いてみる、外部連携を試してみる、などに手をつけてみると良いのかな?と思います。

実際に LoopBack を使ったアプリ開発をするなら、Web 上の資料をまとめてくださっている記事があるので、一通り目を通しておくと良さそう。

感想

REST API の構築がすごく簡単で、いくつかコマンドを打ち込むだけでできてしまいました。

ちょうどタイミングよく Web API The Good Parts を読んでいたところなのですが、
API の設計や、セキュリティや、外部 API との連携といった、そういった考えや知識を必要としないのは良いなーと思います。

LoopBack のようなフレームワークがあることで、デファクトスタンダードができ、私たち開発者一人一人が「ベストは何か」を考える必要がなくなっていくのは良いことだと、最近思っています。
Rails の生みの親が唱える「設定より規約(CoC)」と同じで、より私たちが考えるべき問題に集中できるからです。

LoopBack がそういう立ち位置にはならないかもしれませんが、軽量な API サーバを立ち上げるには十分なフレームワークですし、今後もスピードが求められる場面で使ってみたいなと思えました。

余裕があれば、今度 React-LoopBack に挑戦してみたいなと思います!

参考