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

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

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

URL 方法 アクション
/1.0/:クラス名 役職 新しいオブジェクトを作成
/1.0/:クラス名/:id 取得する オブジェクトを読み取る
/1.0/:クラス名/:id プット オブジェクトを変更する
/1.0/:クラス名/:id 削除 オブジェクトを削除
/1.0/:クラス名 取得する クエリ オブジェクト リスト

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

新しいオブジェクトを作成するには、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 であり、応答の本文は JSON オブジェクトであり、新しいオブジェクトの objectId と createdAt タイムスタンプが含まれます。

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

オブジェクトを読み取る

オブジェクトを作成するとき、返されたヘッダーの Location に 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 リクエストを送信します。指定していないキーは変更されないため、オブジェクト データのサブセットのみを更新できます。たとえば、オブジェクトの age フィールドを変更してみましょう。

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"}
等しくない {"名前":{"ネ":"トム"}}
gt 以上 {"年齢":{"gt":"24"}}
ゲート 以上 {"年齢":{"gte":"24"}}
それは 未満 {"年齢":{"lt":"24"}}
以下 {"年齢":{"Lte":"24"}}
お気に入り ファジークエリ {"名前":{"いいね":"%m"}}
好きじゃない ファジークエリ {"名前":{"not_like":"%m"}}
の間に 間隔比較 {"年齢":{"間の":[22,25]}}
not_between 間隔比較 {"年齢":{"not_between":[22,25]}}
列挙する {"名前":{"in":["トム","ユリ"]}}
ありませんで 列挙する {"名前":{"not_in":["トム","ユリ"]}}
または OR演算 {"または":[{"名前":"トム"},{"年齢":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 つのフィールド2 つのフィールドを含む結果が返され、それぞれが結果の合計数で構成されています。

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/:クラス名/:id/:extendName プット 拡張オブジェクトの設定
/1.0/:クラス名/:id/:extendName 役職 拡張オブジェクトを作成する
/1.0/:クラス名/:id/:extendName/:rid 取得する 拡張オブジェクトの読み取り
/1.0/:クラス名/:id/:extendName/:rid プット 拡張オブジェクトを変更する
/1.0/:クラス名/:id/:extendName/:rid 削除 拡張オブジェクトの削除
/1.0/:クラス名/: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禁止して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形式のクラス図を描画するために使用でき、ファイルは次のような画像に保存されます。 ダイアグラム