LoopBackメモ

LoopBackはNode.js + ExpressをベースにしたREST APIなバックエンドを開発するためのフレームワークです。
モデルを作るだけでそのモデルに対応したREST APIができてしまう容易さがあります。サーバーサイドもクライアントサイドもJSで開発する人たち向きですね。

# Application generator の選択

StrongLoopはIBMに買収されているので `npm i -g strongloop` ではなく、IBM API Connectな `npm i -g apiconnect` とすべきなのかもしれません。
しかしながら、ほいほい囲い込まれるのもなんなのでとりあえず試すならば `npm install -g loopback-cli` です。

http://loopback.io/doc/en/lb3/
LoopBack 3.xのドキュメントではloopback-cliを入れろとありますね。

https://loopback.io/doc/en/lb3/Application-generator.html
loopback-cliをインストールすると `lb app` でプロジェクトのファイル一式を生成することができます。

## バージョン 2.x か 3.x か?

Long-term supportなLoopBack 2.xを選択したくなりますが、LoopBack関連の主要モジュールは3.xに移行してsemverも守られていないようなのでバージョン3.xに突き進むのが無難ではないかと思います。

## Environment-specific configuration

https://loopback.io/doc/en/lb3/Environment-specific-configuration.html
Application generatorで生成されたプロジェクトではconfig.json等、JSONでの設定になっています。
これは、config.jsのようにJavaScriptコードでの設定も可能です。JSONではパスワードでも直書きするしかないよ。

# Models

## automigrateの挙動が気になる

※データベースにPostgreSQLを使っています。loopback-connector-postgresqlに依存した挙動かもしれません。

### カラム順が気になる

モデルにidInjectionを記述してautomigrateすると主キーのidカラムが追加されるものの、先頭ではなくて後ろの方に配置されます。
気になるのでpropertiesの最初にid追加して対応しました。カラム順はindex指定で変更できるっぽいです。
https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html#id-properties

```js
    "id": {
      "type": "number",
      "id": true,
      "generated": true,
      "description": "ID"
    },
```

## Mixins

https://loopback.io/doc/en/lb3/Defining-mixins.html
レコードの登録日時や更新日時といった定型的なあれやこれやはmixinを使うとまったく簡単に対応できてしまう神機能です。使いましょう。
common/mixins/timestamp.jsがドキュメントに載っていますが、これをコピペせずに `npm install loopback-ds-timestamp-mixin --save` しましょう。https://github.com/clarkbw/loopback-ds-timestamp-mixin
READMEを読みましょう。こういうのをどしどし開発してくださいお願いします。

## remote method

- [LoopBackフレームワークでCSV出力API実装](http://qiita.com/shimitei/items/9603701dc7cd8d20a69d)  
シフトJISエンコードでStreamな出力。  
findでリレーションも含めた検索も。

### remote hooks

https://loopback.io/doc/en/lb3/Remote-hooks.html
リモートメソッドの前や後に処理を行うことができる。
loginメソッドもまるっと差し替えるのは手間だけど、afterRemoteで追加のログイン可否条件を処理するのは比較的簡単に対応できる。
ログイン拒否してステータスコード401を返したい場合には次のようにする。

```js
const err = new Error();
err.statusCode = 401;
next(err);
```

## acls

https://loopback.io/doc/en/lb3/Controlling-data-access.html
モデルへのアクセスコントロールなんですが、これベストプラクティスとかあるんでしょうか？
細々設定するのは面倒なのでとりあえず以下のようにしてしまいます。
everyoneは全拒否DENY、ログインしてるauthenticatedはREAD許可、登録更新したいならそれ用のROLEを用意する。

```js
  "acls": [
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "DENY"
    },
    {
      "accessType": "READ",
      "principalType": "ROLE",
      "principalId": "$authenticated",
      "permission": "ALLOW"
    },
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "roleFoo",
      "permission": "ALLOW"
    }
  ],
```

安易にこうするとUserのaccessTokenもだだもれてしまうので、accessToken系のAPIは無効にしてみたりの泥縄。

```js  
  User.disableRemoteMethodByName('prototype.__count__accessTokens');  
  User.disableRemoteMethodByName('prototype.__create__accessTokens');  
  User.disableRemoteMethodByName('prototype.__delete__accessTokens');  
  User.disableRemoteMethodByName('prototype.__destroyById__accessTokens');  
  User.disableRemoteMethodByName('prototype.__findById__accessTokens');  
  User.disableRemoteMethodByName('prototype.__get__accessTokens');  
  User.disableRemoteMethodByName('prototype.__updateById__accessTokens');
```

# Client SDK

https://loopback.io/doc/en/lb3/Client-SDKs.html
LoopBackフレームワークでmBaaSなバックエンドはばっちり。
クライアント側の各種SDKもあるよ。
Angular2以降派は@mean-expert/loopback-sdk-builderですね。
https://github.com/mean-expert-official/loopback-sdk-builder

# デバッグ

http://loopback.io/doc/en/lb3/Setting-debug-strings.html
環境変数DEBUGの値に設定することでいろいろ確認することができます。