読者です 読者をやめる 読者になる 読者になる

LoopBack (Open SourceのBaaS)を使ってみよう! その1. PostgreSQL接続とTwitter認証

あるiOSアプリを作ろうとしています、このアプリはバックエンドのサーバーと情報をやり取りします。バックエンドのサーバーはRuby on Railsで作ってもよいのですが、なるべく早くプロトタイプを動かしたいので、今回は既存のBaaS(Backend as a Service)を使ってみる事にしました。

LoopBack Architecture!

1. なぜ LoopBack を使う事にしたのか

現在BaaSのサービス、Open Sourceのソフトはたくさんあります。ネット上でいろいろと調べてみると BaaS にもサービスよりのものとプラットフォームよりのものがあります(この分類は、私がそう思っているだけかもしれません)。

サービスより のもとしては、実際に良く使われている Parse があげられます。Parseはプッシュ通知やアプリのデータ同期・共有などを複数のプラットフォーム(iOS,Android,PC...)に提供するサービスです。

プラットフォームより のものとしては、Loopbackや以前は話題になったdeploydなどがあります。これらはスマフォとやり取りするAPIサーバーを構築するためのフレームワーククラウドです。 LoopbackはOpen Sourceのソフトですが、それをクラウドで提供するStrongLoopのような会社もあります。

BaaSは現在も進化・競争している世界で、どのサービス・ソフトが良いのかは 簡単には決められない世界のようです。詳しくはBaaSはまだ戦国時代だったのか、まとめ。(執筆中)が参考になります。

今回、Loopbackを使う事にした理由は

  • プラットフォームよりで、今回作るアプリに適切
  • Open Sourceなので、突然のサービス停止にも泣かない
  • ドキュメントもそれなりにある
  • いろいろとサンプルコードがある
  • Node.jsベース。Node.jsはまだまだ初心者ですが Ruby/Railsの世界感にも近い
  • サーバーを自前で準備する必要があるが、このへんは慣れいてる

2. LoopBack入門

a. 前提条件

LoopBackを使うには、Node.js を使って簡単なWebアプリを作れる知識・経験が必要だと思います。

  • JavaScript
  • Node.js
  • npm コマンド
  • 英語ドキュメントが読める (LoopBackの日本語の情報はほぼありません)

b. 入門

  1. node.jsのインストール (v0.10.xを使って下さい。v0.11.xでは動きません)
  2. LoopBackのGetting startedページを試す
    • Ruby on Railsの scaffold のようなものです
    • Modelを定義すると、そのモデルのCRUD操作が出来るREST APIサーバーが出来ます
    • プロジェクトの構成、設定ファイルの役割等を知って下さい
  3. ドキュメントを読みましょう(先にExamplesを試しても良いですが、たぶん読まないと詰まります)
  4. LoopBackのExamplesの興味があるものを試す
    • Examplesのリンク先はGitHubです
    • 詳しい手順が書かれています。たいてい git clone して設定ファイル等を変更し実行する流れです
    • 手順通りにやっても動かない事もままあります。がんばって対応しましょう、とても勉強になります ^^;
    • コードはJavaScriptで書かれています、問題になっているコードを読んでみましょう

3. LoopBackをPostgreSQLにつなぐ

概要

LoopBackはいろいろなDBと接続出来るようになっていますが、大きく2つのタイプがあります

  • MongoDBのようなダイナミックDB
    • このタイプのDBを使う場合はModelにはプロパティー(カラム)の定義が不要です
    • Examplesで使われている Memory もこのタイプです
    • Node.js的にはこのタイプのDBを使うのがお手軽でよいのかもしれません
    • RDBを使う場合も、まず Memory 等で動作を確認してからRDBに置き換えると良いと思います
  • RDB
  • 先ずはGitHubloopback-example-databaseをcloneして動かしてみるのが良いと思います
  • ドキュメントはData sources and connectorsPostgreSQLをつかうならPostgreSQL connector

設定ファイル

LoopBackではDBと接続するための設定ファイルがいくつかあります

  • server/datasources.json : 接続するDBの定義ファイル。
    • 複数のDBを使う事が出来ます
    • Memory DBは最初から定義されています
    • PostgreSQLの定義ファイルにはDatabase名、login、passwordやサーバーなどの情報を書きます、他のソフトでもよくあるものだと思います。
{
  "db": {
    "name": "db",
    "connector": "memory"
  },
  "pgDB": {
    "name": "pgDB",
    "connector": "postgresql",
    "port": 5432,
    "debug": true,
    "database": "node_test",
    "username": "node_test",
    "password": "node_test"
  }
}
  • server/model-config.json: Modelの一覧と、Modelが使うDBなどの定義。
    • 最初の _meta の sources は Modelファイルのある場所のリスト
{
  "_meta": {
    "sources": [
      "../common/models",
      "./models",
      "./node_modules/loopback-component-passport/lib/models"
    ]
  },
  "user": {
    "dataSource": "pgDB",
    "public": true
  },
    ....
  "Role": {
    "dataSource": "db",
    "public": false
  }
}
  • common/models/Model名.json : Modelの定義
    • 対応するRDBのテーブル名、カラム名、型や関連などを定義します
    • optionsを指定する事で、細かいテーブル・カラムの設定が書けます
    • 定義の意味はData sources and connectorsと下位のページに書かれていますが、全てが網羅された情報は無いようです(?)
    • デフォルトでは、Model名、プロパティー名がテーブル名、カラム名にそのまま使われます。対応を変えたい場合はoptionsで指定する必要があります
    • テーブルにはプライマリーキーが必要です、idInjectionをtrueにすればRailsのように整数型のidカラムが自動生成されます
    • 関連情報relationsにはRails同様に hasMany, belongsTo が定義出来ます
{
  "plural": "users",
  "base": "User",
  "options": { "postgresql": { "table": "users" } },
  "idInjection": true,
  "properties": {
    "username": {
      "type": "String",
      "required": true
    },
    "password": {
      "type": "String",
      "required": true
    }
  },
  "relations": {
    "accessTokens": {
      "type": "hasMany",
      "model": "accessToken",
      "foreignKey": "userId"
    }
  },
  "validations": [],
  "acls": [],
  "methods": []
}
  • 他の例
    • 特定のカラムをプライマリーキーにしたい場合は、idInjectionをfalseにし、プロパティーにid属性を指定をします。
{
  "name": "accessToken",
  "plural": "accessTokens",
  "base": "AccessToken",
  "options": { "postgresql": { "table": "access_tokens" } },
  "idInjection": false,
  "properties": {
    "id": {
      "type": "String",
      "id": 1,
      "required": false
    },
    "ttl": {
      "type": "Number",
      "required": false
    },
    "userId": {
      "type": "Number",
      "postgresql": { "columnName": "user_id" },
      "required": false
    },
    "created": {
      "type": "Date",
      "required": false
    }
  },
  "validations": [],
  "relations": {},
  "acls": [],
  "methods": []
}
  • server/create-test-data.js : テーブルの作成とテストデータの作成
    • このファイルは自動生成されないので、Exampleからコピーして作る必要があります。
var server = require('./server');
var dataSource = server.dataSources.accountDB;
var Account = server.models.account;
var accounts = [
    { email: 'foo@bar.com',
      created: new Date(),
      modified: new Date()
    }, {
      email: 'bar@bar.com',
      created: new Date(),
      modified: new Date()
    } ];

var count = accounts.length;
dataSource.automigrate('account', function(er) {
  if (er) throw er;
  accounts.forEach(function(account) {
    Account.create(account, function(er, result) {
      if (er) return;
      console.log('Record created:', result);
      count--;
      if(count === 0) {
        console.log('done');
        dataSource.disconnect();
      }
    });
  });
});

4. LoopBackでTwitter/Facebookの認証を使う

概要

LoopBackにはThird-party loginとい機能があり、これを使うと簡単にTwitter/Facebookの認証を使う事ができます。

設定ファイル

設定ファイルは providers.json で loopback-example-passportには providers.json.template が用意されているのでコピーして使ってください。

{
  "local": {
    "provider": "local",
    "module": "passport-local",
    "usernameField": "username",
   ...
  "twitter-login": {
      "provider": "twitter",
      "authScheme": "oauth",
      "module": "passport-twitter",
      "callbackURL": "http://localhost:3000/auth/twitter/callback",
      "authPath": "/auth/twitter",
      "callbackPath": "/auth/twitter/callback",
      "successRedirect": "/auth/account",
      "consumerKey": "ここにconsumerKeyを指定",
      "consumerSecret": "ここにconsumerSecretを指定"
  },
    ....
}

5. LoopBackでPostgreSQL接続とTwitter認証

PostgreSQLに接続し、Twitter認証が行えるようにしてみました。 GitHubloopback-example-passportをPostgreSQL対応した例 を置きました、これを参考にして下さい。

  • PostgreSQLのテーブル定義は、後々の事を考えRuby on Railsのルールに合わせました
  • providers.jsonTwitterの consumerKey, consumerSecretを入手し作って下さい
  • server/create-test-data.js を実行するとテーブルが作成されます
  • loopback-example-passportは Memoryを使っているので、user モデルにカラム定義がありませんが server/datasources.json に file属性を指定するとDBをファイルにJSONで保存してくれるのでそれを見てカラム定義は作りました
  • user モデル以外の認証に必要なモデルの定義はThird-party+loginに書かれています

ドキュメントには書かれてない部分があったり、callbackの中で起こるエラーはtracebackが在っても役に立たず苦労しました ^^);