素晴らしいコミュニティモジュール

fib-app

fibjsアプリケーションの基本的なAPIフレームワーク

インストール

1
npm install fib-app [--save]

テスト

1
npm test

基本的なスクリプトを作成する

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
const http = require('http'); const util = require('util') const Session = require('fib-session') const App = require('../'); var app = new App('sqlite:test.db', { uuid: true }); app.db.use(require('./defs/person')); var session = new Session(new util.LruCache(20000), { timeout: 60 * 1000 }); var svr = new http.Server(8080, [ session.cookie_filter, { '/1.0': app } ]); svr.run();

ここでperson次のようにモデル定義モジュールは、次のとおりです。

1 2 3 4 5 6 7
module.exports = db => { db.define('person', { name: String, sex: ["male", "female"], age: Number }); };

これは標準のorm定義であり、型チェックやイベントなど、ormの他の機能も使用できます。

APIデータ形式

POSTおよびPUTリクエストの場合、リクエストの本文はJSON形式である必要があり、HTTPヘッダーのContent-Typeをapplication / jsonに設定する必要があります。

1 2 3 4
curl -X PUT \ -H "Content-Type: application/json" \ -d '{"name": "tom","sex":"male","age":23}' \ http://localhost/1.0/person/57fbbdb0a2400000

すべてのリクエストで、応答形式はJSONオブジェクトです。

リクエストの成功は、HTTPステータスコードによって示されます。2XXステータスコードは成功を示し、4XXは要求の失敗を示します。リクエストが失敗した場合でも、レスポンスの本文はJSONオブジェクトのままですが、デバッグに使用できるコードとメッセージの2つのフィールドが常に含まれます。たとえば、権限認証の要求が失敗した場合、次の情報が返されます。

1 2 3 4
{ "code": 4030501, "message": "The operation isn’t allowed for clients due to class-level permissions." }

コードは3つの部分に分かれています。最初の3桁の403はエラーの種類を示し、05はデータテーブル番号を示し、01は詳細なエラーコードを示します。

GETリクエストの場合、通常はオブジェクトデータが返されます。GETリクエストのアドレスによっては、オブジェクトまたは配列が返される場合があります。例えば:

1 2 3 4 5
{ "name": "tom", "sex": "male", "age": 23 }

また:

1 2 3 4 5 6 7 8 9 10 11 12
[ { "name": "tom", "sex": "male", "age": 23 }, { "name": "lily", "sex": "female", "age": 22 } ]

専門分野

オブジェクトデータには、APIを介して変更できない特別な意味を持つ4つのフィールドがあります。それぞれidupdatedAtcreatedAtcreatedBy

ここでidupdatedAtcreatedAt個々のフィールドが自動的に作成され、変更されます。createdByタイプは自分で指定する必要があります。

基本的なオブジェクトアクセスAPI

このデータ定義を完了すると、RESTapi仕様に準拠するインターフェイス呼び出しの完全なセットが直接得られます。

URL 方法 アクション
/1.0/:className 役職 新しいオブジェクトを作成する
/1.0/:className/:id 得る オブジェクトの読み取り
/1.0/:className/:id 置く オブジェクトを変更する
/1.0/:className/:id 消去 オブジェクトを削除する
/1.0/:className 得る クエリオブジェクトリスト

新しいオブジェクトを作成する

新しいオブジェクトを作成するには、POSTリクエストをクラスのURLに送信する必要があります。このURLには、オブジェクト自体が含まれている必要があります。たとえば、上記のようにオブジェクトを作成するには、次のようにします。

1 2 3 4
curl -X POST \ -H "Content-Type: application/json" \ -d '{"name": "tom","sex":"male","age":23}' \ http://localhost/1.0/person

作成が成功すると、HTTP応答は201 Createdになり、応答の本文は、新しいオブジェクトのobjectIdとcreatedAtタイムスタンプを含むJSONオブジェクトになります。

1 2 3 4
{ "createdAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" }

オブジェクトの読み取り

オブジェクトを作成するときに、返されたヘッダーの場所にGETリクエストを送信することで、そのコンテンツを取得できます。たとえば、上記で作成したオブジェクトを取得するには、次のようにします。

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000

本体は、JSONオブジェクトは、すべてのユーザ供給フィールドとともに含ま戻りcreatedAtupdatedAtそしてidフィールドを:

1 2 3 4 5 6 7 8
{ "name": "tom", "sex": "male", "age": 23, "createdAt": "2017-11-25T01:39:35.931Z", "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" }

を提供することによってフィールドを返しますkeys。カスタマイズされたコンテンツを返すことができます。keysコンテンツは,分割されたフィールド名の文字列にあります。

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000?keys=name%2Csex

戻ります:

1 2 3 4
{ "name": "tom", "sex": "male" }

オブジェクトを変更する

オブジェクトの既存のデータを変更するには、オブジェクトの対応するURLにPUTリクエストを送信できます。指定していないキーは変更されないため、オブジェクトデータのサブセットのみを更新できます。たとえば、オブジェクトの年齢フィールドを変更してみましょう。

1 2 3 4
curl -X PUT \ -H "Content-Type: application/json" \ -d '{"age": 25}' \ http://localhost/1.0/person/57fbbdb0a2400000

JSONオブジェクトが含まれています返されたupdatedAtid更新を示すフィールド時に発生しました:

1 2 3 4
{ "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" }

オブジェクトを削除する

オブジェクトを削除するために、次のように、指定されたオブジェクトのURLにDELETEリクエストを送信できます。

1
curl -X DELETE http://localhost/1.0/person/57fbbdb0a2400000

クエリオブジェクトリスト

クラスのURLにGETリクエストを送信することで、URLパラメータなしで一度に複数のオブジェクトを取得できます。以下は、単にすべてのユーザーを取得するためのものです。

1
curl -X GET http://localhost/1.0/person

戻り値は結果フィールドを含むJSONオブジェクトであり、その値はオブジェクトのリストです。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
[ { "name": "tom", "sex": "male", "age": 23, "createdAt": "2017-11-25T01:39:35.931Z", "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" }, { "name": "lily", "sex": "female", "age": 22, "createdAt": "2017-11-25T01:39:35.931Z", "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400001" } ]

キーフィールドのカスタマイズ

オブジェクトクエリと同様に、クエリリストのkeysカスタムフィールドが結果を返すように設定できます。keysコンテンツは、,分割されたフィールド名文字列に含まれています。次に例を示します。

1
curl -X GET http://localhost/1.0/person?keys=name%2Cage

指定されたリターンのみnameage2つのフィールド。

ここでフィルター条件

Bywhereは、クエリオブジェクトにパラメータとして制約を付けることができます。

whereパラメータの値はJSONでエンコードする必要があります。つまり、実際に送信されたURLリクエストを見ると、最初にJSONエンコードされ、次にURLエンコードされている必要があります。where引数として使用するのが最も簡単なのは、適切なキーと値を含めることです。たとえば、名前がtomのユーザーを検索する場合は、次のようにクエリを作成する必要があります。

1
curl -X GET http://localhost/1.0/person?where=%7B%22name%22%3A%22tom%22%7D

where 値はurlencodeの後のJSON文字列で、内容は次のとおりです。{"name":"tom"}

特定の値を正確に一致させることに加えてwhere、包含などの比較方法もサポートされています。whereパラメータは次のオプションをサポートします。

手術 サンプル
eq 同等 {"name":{"eq": "tom"}}または{"name": "tom"}
ne 等しくない {"name":{"ne": "tom"}}
gt 以上 {"年齢":{"gt": "24"}}
gte 以上以上 {"age":{"gte": "24"}}
lt 未満 {"年齢":{"lt": "24"}}
LTE 以下 {"age":{"lte": "24"}}
お気に入り ファジークエリ {"name":{"like": "%m"}}
好きじゃない ファジークエリ {"name":{"not_like": "%m"}}
の間に 間隔の比較 {"年齢":{"間":[22,25]}}
not_between 間隔の比較 {"年齢":{"not_between":[22,25]}}
列挙する {"name":{"in":["tom"、 "lily"]}}
ありませんで 列挙する {"name":{"not_in":["tom"、 "lily"]}}
また または操作 {"または":[{"name": "tom"}、{"age":24}]}

スキップレコードをスキップ

することでskipオプション、あなたはフリップ効果を達成するために、スキップするレコードの数を指定することができます。

1
curl -X GET http://localhost/1.0/person?skip=100

limitはレコード制限を返します

することでlimitオプションには、返されたレコードの数、制限することができますlimit100から1000まで1〜有効桁およびデフォルトを。

1
curl -X GET http://localhost/1.0/person?limit=100

orderはソート方法を指定します

することでorder、フィールド名が含まれている前に、オプションのセット、結果セットの並べ替え戻す-逆の時間として。

1
curl -X GET http://localhost/1.0/person?order=-id

countは結果の総数を返します

count総数を増やすように要求された場合、指定されたコンテンツの結果セットを同時に返す場合があります。

1
curl -X GET http://localhost/1.0/person?count=1&limit=1

この時点で、countresults2つのフィールドを含み、それぞれが結果の総数で構成される結果を返します。

1 2 3 4 5 6 7 8 9 10 11 12 13
{ "count": 2, "results": [ { "name": "tom", "sex": "male", "age": 23, "createdAt": "2017-11-25T01:39:35.931Z", "updatedAt": "2017-11-25T01:39:35.931Z", "id": "57fbbdb0a2400000" } ] }

拡張オブジェクトを作成する

ormを介してhasOneとhasManyを定義することにより、オブジェクト間の関連付け関係を定義し、APIに反映させることができます。次に例を示します。

1 2 3 4 5 6 7 8 9
module.exports = db => { var Person = db.models.person; var Pet = db.define('pet', { name: String }); Person.hasMany('pets', Pet); };

拡張オブジェクトアクセスAPI

以下は、拡張オブジェクトのAPI定義です。

URL 方法 アクション
/1.0/:className/:id/:extendName 置く 拡張オブジェクトを設定する
/1.0/:className/:id/:extendName 役職 拡張オブジェクトを作成する
/1.0/:className/:id/:extendName/:rid 得る 拡張オブジェクトを読み取る
/1.0/:className/:id/:extendName/:rid 置く 拡張オブジェクトを変更する
/1.0/:className/:id/:extendName/:rid 消去 拡張オブジェクトを削除する
/1.0/:className/:id/:extendName 得る 拡張オブジェクトのリストを照会する

拡張オブジェクトを設定する

拡張オブジェクトの設定は、2つの独立したオブジェクト間の接続を確立することです。たとえば、トムは猫という名前のペットを採用しました。これは、次の操作で実現できます。

1 2 3 4
curl -X PUT \ -H "Content-Type: application/json" \ -d '{"id": "57fbbdb0a2400007"}' \ http://localhost/1.0/person/57fbbdb0a2400000/pets

呼び出しでは、猫のIDを本文で指定する必要があります。

拡張オブジェクトを作成する

拡張オブジェクトを直接作成することにより、オブジェクトの作成中にオブジェクト間の接続を確立できます。例えば:

1 2 3 4
curl -X POST \ -H "Content-Type: application/json" \ -d '{"name": "cat"}' \ http://localhost/1.0/person/57fbbdb0a2400000/pets

猫という名前のペットが作成され、トムとの関係が確立されます。

拡張オブジェクトを読み取る

拡張オブジェクトの読み取りは、ベースオブジェクトの読み取りと非常によく似ており、キーオプションもサポートしています。

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007

拡張オブジェクトを変更する

拡張オブジェクトの読み取りは、ベースオブジェクトの読み取りと非常によく似ています。

1 2 3 4
curl -X PUT \ -H "Content-Type: application/json" \ -d '{"name": "cat 1"}' \ http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007

拡張オブジェクトを削除する

拡張オブジェクトを削除しても、オブジェクト自体は削除されませんが、オブジェクト間の関係が削除されるだけです。

1
curl -X DETELE http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007

拡張オブジェクトのリストを照会する

拡張オブジェクトリストのクエリは、基本オブジェクトリストのクエリと非常によく似ており、キーや条件付きフィルタリングなどのオプションもサポートしています。

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000/pets

ACL

モデルのACLを定義することにより、データのアクセス許可を制御できます。例えば:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
const orm = require('fib-orm'); module.exports = db => { db.define('blog', { title: String, detail: Stringnote: String }, { ACL: function(session) { return { "*": { "*": false }, "57fbbdb0a2400000": { "*": true }, "roles": { "user": { "read": true } } }; } }); };

モデルの定義時にACLが指定されていない場合は、デフォルトのアクセス許可を設定するのと同じです。

1 2 3 4 5
{ "*": { "*": true } }

本体

三つの主要なACLの説明、利用者がありid、利用者role*id特定のユーザーを表すroleユーザーが役割を持っていることを示す、*意味、すべてのユーザーそれは:

本体 説明 優先順位
id 特定のユーザーのID 1
役割 ユーザーグループ名 2
* 全て 3

特権をチェックするとき、最初はid対応する権限と一致します(指定されていない場合)。一致するユーザーrole権限は、指定されている場合は引き続き対応し、指定された*権限(*指定されていない場合)に権限がないかどうかを確認します。

たとえば、上記の権限構成では、userユーザーグループが読み取ることができ、ユーザー57fbbdb0a2400000が完全な権限を持ち、他のユーザーが権限を持たないことを指定します。

権限

ACLは、APIの動作に基づいて5種類の権限を分類します。

権限 説明 許可されるタイプ
作成 オブジェクトを作成する true / false /配列
読んだ オブジェクトの読み取り true / false /配列
書きます オブジェクトを変更する true / false /配列
消去 オブジェクトを削除する 真/偽
探す クエリオブジェクトリスト 真/偽
* すべての権限に一致 true / false /配列

アクセスを許可trueし、アクセスをfalse禁止してarray指定されたアクセスフィールドのみ許可するために開発されたアクセス許可deleteそして、find受け付けません。arrayあなたが設定された場合、arrayその後見なさtrue指定された権限が存在しない場合、次は主な*権限と一致します。存在しない場合は、次の優先度の件名を再度照会します。

上記の例の例では、設定する必要がある場合userは読み取りのみが許可されtitledetail他のユーザーは読み取り可能である場合 title、次のように設定できます。

1 2 3 4 5 6 7 8 9 10 11 12 13 14
{ "*": { "*": false, "read": ['title'] }, "57fbbdb0a2400000": { "*": true }, "roles": { "user": { "read": ['title', 'detail'] } } }

オブジェクトのアクセス許可

クラス全体の権限はモデルで設定されます。特定のオブジェクトの権限を設定する必要がある場合は、次のことを実現するようにOACLを設定できます。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
module.exports = db => { db.define('person', { name: String, sex: ["male", "female"], age: Number }, { ACL: function(session) { return { "*": { "*": false } } }, OACL: function(session) { var _acl = {}; if(this.id === session.id) _acl[session.id] = { "*": true }; return _acl; } }); };

この例では、訪問者が対象である場合、すべての操作が許可されます。それ以外の場合、すべての訪問が禁止されます。権限は、次の手順に従ってチェックされます。

  • person[57fbbdb0a2400000] => OACL
  • person => ACL

拡張オブジェクトのアクセス許可

拡張オブジェクトのアクセス許可制御は、基本オブジェクト許可に似ていますが、唯一の違いは、ACLで個別に指定する必要があることです。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
module.exports = db => { var Person = db.define('person', { name: String, sex: ["male", "female"], age: Number },{ ACL: function(session) { return { "*": { "read": ['name', 'sex'], "extends": { "pets": { "read": true, "find": true } } } } }, OACL: function(session) { var _acl = {}; if(this.id === session.id) _acl[session.id] = { "*": true, "extends": { "pets": { "*": true } } }; return _acl; } }); var Pet = db.define('pet', { name: String }); Person.hasMany('pets', Pet); };

この定義は、誰もが個人情報にアクセスすることができますnamesex、無料のアクセスと、彼を検索しpets、私は、ユーザーが自分のデータのすべてを動作させることができています、そして全ての権利は、自分のペットの情報を持っています。

拡張オブジェクトのアクセス権限をチェックする場合、オブジェクト権限と拡張オブジェクト権限は別々にチェックされます。たとえば、次のリクエスト:

1
curl -X GET http://localhost/1.0/person/57fbbdb0a2400000/pets/57fbbdb0a2400007

権限は、次の手順に従ってチェックされます。

  • pets[57fbbdb0a2400007] => OACL
  • person[57fbbdb0a2400000]=> OACL=> extends=>pets
  • person=> ACL=> extends=>pets
  • pets => ACL

関数

モデルに対してAPIを定義でき、関数をカスタマイズすることで複雑なデータ操作を完了できます。

権限の大部分はACLによって制御でき、オブジェクトベースの権限を完了するために機能は必要ありません。関数を使用して、承認ステータスに基づいてさまざまなユーザーグループにアクセス許可を付与するなど、データベースのアクセス許可を完了することができます。また、複数のデータベースレコードを変更する必要があるなど、複数の変更。

データモデルを描く

データ定義の完了後、app.diagram()データモデルsvg形式のクラス図を描画するために使用できます。ファイルは次のような画像に保存されます。 図