言うまでもなく、アプリケーション開発におけるNode.jsの人気が高まっています。 eBayは2011年から本番のNodeAPIサービスを実行しています。PayPalはNodeでフロントエンドを積極的に再構築しています。ウォルマートのモバイルサイトは、トラフィックに関して最大のノードアプリケーションになりました。 2014年の感謝祭の週末に Walmartサーバーは15億のリクエストを処理しました 、その70%はモバイル経由で配信され、Node.jsを利用しています。開発側では、ノードパッケージマネージャー( 海抜 )は急速に成長を続けており、最近では150,000のホストモジュールを超えています。
一方 RubyにはRailsがあります そして Python Nodeの主要なアプリケーション開発フレームワークであるDjangoはまだ確立されていません。しかし、勢いを増している強力な競争相手がいます: ループバック 、カリフォルニア州サンマテオの会社によって構築されたオープンソースAPIフレームワーク StrongLoop 。 StrongLoopは最新の重要な貢献者です ノードバージョン 、の長年のメンテナは言うまでもありません Express 、存在する中で最も人気のあるノードフレームワークの1つ。
すべてを実践に移し、サンプルアプリケーションを構築することで、LoopBackとその機能を詳しく見ていきましょう。
LoopBackは APIの作成 それらをバックエンドデータソースに接続します。 Expressの上に構築されており、データモデル定義を取得し、任意のクライアントから呼び出すことができる完全に機能するエンドツーエンドのRESTAPIを簡単に生成できます。
LoopBackには、組み込みのクライアントが付属しています。 APIエクスプローラー 。これを使用すると、作業の結果が見やすくなり、この例ではAPI自体の構築に焦点を当てることができます。
もちろん、フォローするには、マシンにNodeをインストールする必要があります。それを得る ここに 。 npmが付属しているので、必要なパッケージを簡単にインストールできます。始めましょう。
私たちのアプリケーションは、ギフトを必要としている可能性のある人に、ギフトや不要になったものを寄付したい人を管理します。したがって、ユーザーはドナーとレシーバーになります。寄付者は新しいギフトを作成し、ギフトのリストを見ることができます。受信者は、すべてのユーザーからのギフトのリストを表示でき、未請求のギフトを請求できます。もちろん、同じエンティティ(ユーザー)上でドナーとレシーバーを別々のロールとして構築することもできますが、LoopBackでリレーションを構築する方法を確認できるように、それらを分離してみましょう。この画期的なアプリケーションの名前は Givesomebody 。
npmを介してStrongLoopコマンドラインツールをインストールします。
$ npm install -g strongloop
次に、LoopBackのアプリケーションジェネレーターを実行します。
$ slc loopback _-----_ | | .--------------------------. |--(o)--| | Let's create a LoopBack | `---------´ | application! | ( _´U`_ ) '--------------------------' /___A___ | ~ | __'.___.'__ ´ ` |° ´ Y ` ? What's the name of your application? Givesomebody
モデルを追加しましょう。私たちの最初のモデルはギフトと呼ばれます。 LoopBackは、データソースと基本クラスを要求します。データソースをまだ設定していないので、db (memory)
を入力できます。基本クラスは自動生成されたモデルクラスであり、PersistedModel
を使用します。この場合、通常のCRUDメソッドがすべてすでに含まれているためです。次に、LoopBackは、RESTを介してモデルを公開する必要があるかどうか(yes)、およびRESTサービスの名前を尋ねます。ここでEnterキーを押すと、デフォルトが使用されます。これは、モデル名の複数形(この場合はgifts
)です。
$ slc loopback:model ? Enter the model name: Gift ? Select the data-source to attach Gift to: (Use arrow keys) ❯ db (memory) ? Select model's base class: (Use arrow keys) Model ❯ PersistedModel ? Expose Gift via the REST API? (Y/n) Yes ? Custom plural form (used to build REST URL):
最後に、プロパティの名前、それらのデータ型、および必須/非必須フラグを示します。ギフトにはname
がありますおよびdescription
プロパティ:
Let's add some Gift properties now. Enter an empty property name when done. ? Property name: name invoke loopback:property ? Property type: (Use arrow keys) ❯ string ? Required? (y/N)Yes
空のプロパティ名を入力して、プロパティの定義が完了したことを示します。
モデルジェネレーターは、アプリケーションのcommon/models
でモデルを定義する2つのファイルを作成します:gift.json
およびgift.js
。 JSONファイルは、エンティティに関するすべてのメタデータ(プロパティ、リレーション、検証、ロール、メソッド名)を指定します。 JavaScriptファイルは、追加の動作を定義し、特定の操作(作成、更新、削除など)の前後に呼び出されるリモートフックを指定するために使用されます。
他の2つのモデルエンティティは、ドナーモデルとレシーバーモデルになります。今回はUser
を入れますが、同じプロセスを使用して作成できます。基本クラスとして。 username
、password
、email
などのプロパティが表示されます箱から出して。たとえば、名前と国だけを追加して、完全なエンティティを作成できます。受信者の場合は、配送先住所も追加します。
生成されたプロジェクト構造を見てみましょう。
3つの主要なディレクトリは次のとおりです。-/server
–ノードアプリケーションスクリプトと構成ファイルが含まれています。 -/client
– .js、.html、.css、およびその他すべての静的ファイルが含まれます。 -/common
–このフォルダーは、サーバーとクライアントの両方に共通です。モデルファイルはここにあります。
各ディレクトリの内容の詳細な内訳は、 LoopBackドキュメント :
ファイルまたはディレクトリ | 説明 | コードでアクセスする方法 |
---|---|---|
トップレベルのアプリケーションディレクトリ | ||
package.json | 標準のnpmパッケージ仕様。見る package.json | 該当なし |
/ serverディレクトリ-ノードアプリケーションファイル | ||
server.js | メインアプリケーションプログラムファイル。 | 該当なし |
config.json | アプリケーションの設定。見る config.json 。 | app.get('setting-name') |
datasources.json | データソース構成ファイル。見る datasources.json 。例については、を参照してください。 新しいデータソースを作成する 。 | app.datasources['datasource-name'] |
model-config.json | モデル構成ファイル。見る model-config.json 。詳細については、を参照してください。 モデルをデータソースに接続する 。 | 該当なし |
middleware.json | ミドルウェア定義ファイル。詳細については、を参照してください。 ミドルウェアの定義 。 | 該当なし |
/boot ディレクトリ | 初期化とセットアップを実行するスクリプトを追加します。見る ブートスクリプト 。 | スクリプトはアルファベット順に自動的に実行されます。 |
/ clientディレクトリ-クライアントアプリケーションファイル | ||
README.md | LoopBackジェネレーターは、マークダウン形式で空のREADMEファイルを作成します。 | 該当なし |
その他 | HTML、CSS、クライアントJavaScriptファイルを追加します。 | |
/ commondirectory-共有アプリケーションファイル | ||
/models ディレクトリ | カスタムモデルファイル:
| ノード: myModel = app.models.myModelName |
この例では、モデル化する重要な関係がいくつかあります。寄付者は多くの贈り物を寄付することができ、それは関係を与えます ドナーはたくさんの贈り物を持っています 。レシーバーもたくさんのギフトを受け取ることができるので、私たちにも関係があります レシーバーにはたくさんのギフトがあります 。反対側では、 ギフトは寄付者のものです 、および レシーバーに属する 受信者がそれを受け入れることを選択した場合。これをLoopBackの言語に入れましょう。
Windowsで書かれたプログラミング言語は何ですか
$ slc loopback:relation ? Select the model to create the relationship from: Donor ? Relation type: has many ? Choose a model to create a relationship with: Gift ? Enter the property name for the relation: gifts ? Optionally enter a custom foreign key: ? Require a through model? No
スルーモデルがないことに注意してください。ギフトへの参照を保持しているだけです。
レシーバーに対して上記の手順を繰り返し、2つ追加すると 属する ギフトとの関係で、バックエンド側でモデル設計を行います。 LoopBackは、モデルのJSONファイルを自動的に更新して、これらの単純なダイアログで行ったことを正確に表現します。
// common/models/donor.json ... 'relations': { 'gifts': { 'type': 'hasMany', 'model': 'Gift', 'foreignKey': '' } }, ...
次に、実際のデータソースをアタッチしてすべてのアプリケーションデータを保存する方法を見てみましょう。この例では、次を使用します MongoDB 、ただし、LoopBackには、Oracle、MySQL、PostgreSQL、Redis、およびSQLServerに接続するためのモジュールがあります。
まず、コネクタを取り付けます。
$ npm install --save loopback-connector-mongodb
次に、プロジェクトにデータソースを追加します。
$ slc loopback:datasource ? Enter the data-source name: givesomebody ? Select the connector for givesomebody: MongoDB (supported by StrongLoop)
次のステップは、server/datasources.json
でデータソースを構成することです。ローカルMongoDBサーバーには次の構成を使用します。
... 'givesomebody': { 'name': 'givesomebody', 'connector': 'mongodb', 'host': 'localhost', 'port': 27017, 'database': 'givesomebody', 'username': '', 'password': '' } ...
最後に、server/model-config.json
を開きますdatasource
を変更しますデータベースに永続化するすべてのエンティティについて、'givesomebody'
。
{ ... 'User': { 'dataSource': 'givesomebody' }, 'AccessToken': { 'dataSource': 'givesomebody', 'public': false }, 'ACL': { 'dataSource': 'givesomebody', 'public': false }, 'RoleMapping': { 'dataSource': 'givesomebody', 'public': false }, 'Role': { 'dataSource': 'givesomebody', 'public': false }, 'Gift': { 'dataSource': 'givesomebody', 'public': true }, 'Donor': { 'dataSource': 'givesomebody', 'public': true }, 'Receiver': { 'dataSource': 'givesomebody', 'public': true } }
これまでに作成したものを確認するときが来ました。すばらしい組み込みツールを使用します。 APIエクスプローラー 、作成したばかりのサービスのクライアントとして使用できます。テストしてみましょう REST API 呼び出します。
別のウィンドウで、次のコマンドでMongoDBを起動します。
$ mongod
次のコマンドでアプリケーションを実行します。
$ node .
ブラウザで、http://localhost:3000/explorer/
に移動します。使用可能な操作のリストを使用してエンティティを確認できます。 POSTで1つのドナーを追加してみてください/Donors
コール。
APIエクスプローラー 非常に直感的です。公開されているメソッドのいずれかを選択すると、対応するモデルスキーマが右下隅に表示されます。 data
でテキスト領域では、カスタムHTTPリクエストを作成できます。リクエストが入力されたら、[試してみる]ボタンをクリックすると、サーバーの応答が下に表示されます。
上記のように、LoopBackで事前に構築されたエンティティの1つはUserクラスです。ユーザーはログインメソッドとログアウトメソッドを所有しており、特定のユーザーのトークンを保持するAccessTokenエンティティにバインドできます。実際、完全なユーザー認証システムは、箱から出してすぐに使用できます。 /Donors/login
に電話をかけようとすると使って APIエクスプローラー 、これが私たちが得る応答です:
{ 'id': '9Kvp4zc0rTrH7IMMeRGwTNc6IqNxpVfv7D17DEcHHsgcAf9Z36A3CnPpZJ1iGrMS', 'ttl': 1209600, 'created': '2015-05-26T01:24:41.561Z', 'userId': '' }
id
実際にはAccessTokenの値であり、自動的に生成されてデータベースに保持されます。ここに表示されているように、アクセストークンを設定して、後続の各リクエストに使用することができます。
リモートメソッドは、モデルの静的メソッドであり、カスタムRESTエンドポイントを介して公開されます。リモートメソッドを使用して、LoopBackの標準モデルRESTAPIでは提供されていない操作を実行できます。
箱から出してすぐに使えるCRUDメソッドのほかに、必要な数のカスタムメソッドを追加できます。それらはすべて[model].js
に入る必要がありますファイル。この例では、Giftモデルにリモートメソッドを追加して、ギフトがすでに予約されているかどうかを確認し、予約されていないすべてのギフトを一覧表示します。
まず、モデルにreserved
というプロパティを追加しましょう。これをgift.json
のプロパティに追加するだけです。
... 'reserved': { 'type': 'boolean' } ...
gift.js
のリモートメソッド次のようになります。
module.exports = function(Gift) { // method which lists all free gifts Gift.listFree = function(cb) { Gift.find({ fields: { reserved: false } }, cb); }; // expose the above method through the REST Gift.remoteMethod('listFree', { returns: { arg: 'gifts', type: 'array' }, http: { path: '/list-free', verb: 'get' } }); // method to return if the gift is free Gift.isFree = function(id, cb) { var response; Gift.find({ fields: { id: id } }, function(err, gift) { if (err) return cb(err); if (gift.reserved) response = 'Sorry, the gift is reserved'; else response = 'Great, this gift can be yours'; }); cb(null, response); }; // expose the method through REST Gift.remoteMethod('isFree', { accepts: { arg: 'id', type: 'number' }, returns: { arg: 'response', type: 'string' }, http: { path: '/free', verb: 'post' } }); };
したがって、特定のギフトが利用可能かどうかを確認するために、クライアントはPOSTリクエストを/api/Gifts/free
に送信し、id
を渡すことができます。問題の贈り物の。
リモートメソッドの前後に何らかのメソッドを実行する必要がある場合があります。 2種類のリモートフックを定義できます。
beforeRemote()
リモートメソッドの前に実行されます。afterRemote()
リモートメソッドの後に実行されます。どちらの場合も、関数を「フック」するリモートメソッドに一致する文字列とコールバック関数の2つの引数を指定します。リモートフックの威力の多くは、文字列にワイルドカードを含めることができるため、任意のマッチング方法によってトリガーされることです。
この場合、新しいドナーが作成されるたびにコンソールに情報を出力するフックを設定しましょう。これを実現するために、donor.js
に「作成前」フックを追加しましょう。
module.exports = function(Donor) { Donor.beforeRemote('create', function(context, donor, next) { console.log('Saving new donor with name: ', context.req.body.name); next(); }); };
要求は、指定されたcontext
およびnext()
で呼び出されます。ミドルウェアのコールバック(以下で説明)は、フックの実行後に呼び出されます。
LoopBackアプリケーションはモデルを介してデータにアクセスするため、データへのアクセスを制御することは、モデルに対する制限を定義することを意味します。つまり、モデルでデータの読み取りと書き込み、またはメソッドの実行を実行できるユーザーまたは対象を指定します。 LoopBackアクセス制御は、アクセス制御リスト(ACL)によって決定されます。
ログインしていないドナーとレシーバーがギフトを表示できるようにしますが、ギフトを作成および削除できるのはログインしているドナーのみです。
$ slc loopback:acl
まず、すべてのエンドポイントへのすべてのアクセスを拒否しましょう。
? Select the model to apply the ACL entry to: Gift ? Select the ACL scope: All methods and properties ? Select the access type: All (match all types) ? Select the role: All users ? Select the permission to apply: Explicitly deny access
次に、誰もがギフトモデルから読むことができるようにします。
$ slc loopback:acl ? Select the model to apply the ACL entry to: Gift ? Select the ACL scope: All methods and properties ? Select the access type: Read ? Select the role: All users ? Select the permission to apply: Explicitly grant access
次に、認証されたユーザーがギフトを作成できるようにします。
$ slc loopback:acl ? Select the model to apply the ACL entry to: Gift ? Select the ACL scope: A single method ? Enter the method name: create ? Select the role: Any authenticated user ? Select the permission to apply: Explicitly grant access
そして最後に、ギフトの所有者が変更を加えることを許可しましょう。
$ slc loopback:acl ? Select the model to apply the ACL entry to: Gift ? Select the ACL scope: All methods and properties ? Select the access type: Write ? Select the role: The user owning the object ? Select the permission to apply: Explicitly grant access
gift.json
を確認すると、すべてが整っているはずです。
'acls': [ { 'accessType': '*', 'principalType': 'ROLE', 'principalId': '$everyone', 'permission': 'DENY' }, { 'accessType': 'READ', 'principalType': 'ROLE', 'principalId': '$everyone', 'permission': 'ALLOW' }, { 'accessType': 'EXECUTE', 'principalType': 'ROLE', 'principalId': '$authenticated', 'permission': 'ALLOW', 'property': 'create' } ],
ここで重要な注意事項:$authenticated
はシステム内のすべてのユーザー(ドナーとレシーバーの両方)に対応する事前定義された役割ですが、ドナーが新しいギフトを作成できるようにするだけです。したがって、カスタムロールが必要です。 Roleは、すぐに使用できるもう1つのエンティティであるため、そのAPI呼び出しを利用して$authenticatedDonor
を作成できます。ブート機能の役割を果たしてから、pricipalId
を変更するだけです。 gift.json
で。
新しいファイルserver/boot/script.js
を作成し、次のコードを追加する必要があります。
Role.create({ name: 'authenticatedDonor' }, function(err, role) { if (err) return debug(err); })
RoleMappingエンティティは、ロールをユーザーにマップします。 RoleとRoleMappingの両方がRESTを介して公開されていることを確認してください。 server/model-config.json
で、'public'
を確認しますtrue
に設定されますRoleエンティティの場合。次に、donor.js
に、userID
をマップする「作成前」フックを記述できます。およびroleID
RoleMapping POSTAPI呼び出しで。
ミドルウェアには、RESTエンドポイントに対して要求が行われたときに実行される関数が含まれています。 LoopBackはExpressに基づいているため、「ミドルウェアフェーズ」と呼ばれる1つの追加概念を備えたExpressミドルウェアを使用します。フェーズは、ミドルウェアの関数が呼び出される順序を明確に定義するために使用されます。
LoopBackのドキュメントで提供されている、事前定義されたフェーズのリストは次のとおりです。
各フェーズには3つのサブフェーズがあります。たとえば、初期フェーズのサブフェーズは次のとおりです。
デフォルトのmiddleware.jsonを簡単に見てみましょう。
{ 'initial:before': { 'loopback#favicon': {} }, 'initial': { 'compression': {}, 'cors': { 'params': { 'origin': true, 'credentials': true, 'maxAge': 86400 } } }, 'session': { }, 'auth': { }, 'parse': { }, 'routes': { }, 'files': { }, 'final': { 'loopback#urlNotFound': {} }, 'final:after': { 'errorhandler': {} } }
初期段階では、loopback.favicon()
と呼びます。 (loopback#favicon
はその呼び出しのミドルウェアIDです)。次に、サードパーティのnpmモジュールcompression
およびcors
呼び出されます(パラメーターありまたはなし)。最終フェーズでは、さらに2つの呼び出しがあります。 urlNotFound
はLoopBack呼び出しであり、errorhandler
サードパーティのモジュールです。この例は、外部npmモジュールと同じように多くの組み込み呼び出しを使用できることを示しているはずです。そしてもちろん、いつでも独自のミドルウェアを作成し、このJSONファイルを介してそれらを呼び出すことができます。
loopback-boot
最後に、boot()
をエクスポートするモジュールについて説明します。アプリケーションを初期化する関数。 server/server.js
でアプリケーションをブートストラップする次のコードがあります。
boot(app, __dirname, function(err) { if (err) throw err; // start the server if `$ node server.js` if (require.main === module) app.start(); });
このスクリプトはserver/boot
を検索しますフォルダを作成し、そこにあるすべてのスクリプトをアルファベット順にロードします。したがって、server/boot
では、開始時に実行する必要のある任意のスクリプトを指定できます。一例はexplorer.js
です。これは実行されます APIエクスプローラー 、APIのテストに使用したクライアント。
私があなたを去る前に、私は言及したいと思います ストロングループアーク 、slc
の代わりに使用できるグラフィカルUIコマンドラインツール。また、ノードアプリケーションを構築、プロファイリング、および監視するためのツールも含まれています。コマンドラインのファンではない人にとって、これは間違いなく試す価値があります。ただし、StrongLoop Arcは廃止されようとしており、その機能は IBM API Connect Developer Toolkit 。
一般的に言って、LoopBackは、箱からたくさんのものを取り出しているので、多くの手作業を節約できます。これにより、アプリケーション固有の問題とビジネスロジックに集中できます。アプリケーションが CRUD操作に基づく 事前定義されたエンティティを操作する場合、多数の開発者がユーザーの認証および承認インフラストラクチャを書き直すことにうんざりしている場合、またはExpressなどの優れたWebフレームワークのすべての利点を活用したい場合は、RESTAPIを次のように構築します。 LoopBackはあなたの夢をかなえることができます。簡単なことです!