コネクタフックは、コネクタの動作によって起動されます。
Page Contents

概要

コネクタは、モデルメソッドに代わってバックエンドシステムと対話する役割を担います。 コネクタフックにより、アプリケーションはコネクタの実行に介入できます。

2つのコネクタフックを使用できます。

  • ‘before execute’
  • ‘after execute’

before execute

‘before execute’フックは、コネクタがバックエンドデータソースに要求を送信する前に呼び出されます。

var connector = MyModel.getDataSource().connector;
connector.observe('before execute', function(ctx, next) {
  // ...
  next();
});

呼び出しを終了するには、次のようにctx.end(err, result)を呼び出します。

var connector = MyModel.getDataSource().connector;
connector.observe('before execute', function(ctx, next) {
  // ...
  ctx.end(null, cachedResponse);
});

after execute

‘after execute’フックは、コネクタがバックエンドデータソースから応答を受け取った後に呼び出されます。

connector.observe('after execute', function(ctx, next) {
  // ...
  next();
});

コンテキスト

コンテキストオブジェクトには、フックが動作するための情報が含まれています。コネクタの種類によって異なります。

リレーショナルデータベースコネクタ

リレーショナルデータベースコネクタ には、MySQL・PostgreSQL・SQL Server・Oracle コネクタなどが含まれます。

before: {req: {sql: 'SELECT ...', params: [1, 2]}, end: ...}
after: {req: {sql: 'SELECT ...', params: [1, 2]}, res: ..., end: ...}

MongoDB コネクタ

before: {req: {command: ..., params: ...}, end: ...}
after: {req: {...}, res: {...}, end: ...}

ここで、

REST コネクタ

before: {req: {...}, end: ...}
after: {req: {...}, res: {...}, end: ...}

ここで、

  • reqrequest モジュールに渡される要求オブジェクトです。
  • resrequest モジュールから受け取った応答オブジェクトです。

コネクタフックは、メソッドの最後までは情報を持たない LoopBackコンテキストオブジェクト ctx にアクセスできるようにします。通常、呼び出しの最後には応答の本体が得られるので、ヘッダーはctxオブジェクト内でのみ使用できます。

アプリケーションの起動時にコネクタフックを使用する必要があります。例えば:

server/boot/set-headers-in-body.js

module.exports = function(server) {
  var APIConnector;
  APIConnector = server.datasources.APIDataSource.connector;
  return APIConnector.observe('after execute', function(ctx, next) {

  });
};

この関数の中で以下の情報にアクセスできます。

  • レスポンスヘッダ: ctx.res.headers
  • HTTP レスポンスコード: ctx.res.body.code
  • リクエストのHTTPメソッド: ctx.req.method

フックは、コネクタが呼び出されるたびに起動されるため、RESTコネクタを使用するすべての要求はこの関数を経由します。

ただし、APIの呼出しはnext()関数を呼び出さないため、APIを呼び出すたびにはこの呼び出しは行われません。

すべてのPOST要求をフックするには、サーバーはヘッダのlocationをボディ内にコピーします。たとえば、次のようにします。

module.exports = function(server) {
  var APIConnector;
  APIConnector = server.datasources.APIDataSource.connector;
  return APIConnector.observe('after execute', function(ctx, next) {
    if (ctx.req.method === 'POST') {
      ctx.res.body.location = ctx.res.headers.location;
      return ctx.end(null, ctx, ctx.res.body);
    } else {
      return next();
    }
  });
};

ctx.end メソッドは、3つの引数を必要とします。errctxresultです。result は、リモートメソッドが呼び出されたときに最後に送信されるものです。

多くのバグを回避するために、ctxに触る場所で、場合分けをしておきます。例えば以下のようにします。

if (ctx.req.method === 'POST'
    && ((ref = ctx.res) != null ? (ref1 = ref.body) != null ? ref1.code : void 0 : void 0) === 200
    && ctx.res.headers.location) {
      // ...
    }

エラー処理

コネクタフックには、APIからの応答を再フォーマットするような、XMLを返すAPIに有効な、多くの用途があります。また、コネクタフックを使用して、APIからのエラーを、プロミス内のモデルに伝わる前に処理することもできます。

APIゲートウェイを使用している場合、HTTPエラー502 Bad Gateway送信されうるすべてのエラーは、403 Forbiddenであるべきです。サーバーエラーとゲートウェイエラーの混乱を避けるため、フックでエラー処理をカスタマイズしてください。例えば以下のようにします。

module.exports = function(server) {
  var APIConnector;
  APIConnector = server.datasources.APIDataSource.connector;
  return APIConnector.observe('after execute', function(ctx, next) {
    var err, ref, ref1;
    if (/^[5]/.test((ref = ctx.res) != null ? (ref1 = ref.body) != null ? ref1.code : void 0 : void 0)) {
      err = new Error('Error from the API');
      err.status = 403;
      err.message = ctx.res.body.message;
      return ctx.end(err, ctx, ctx.res.body);
    } else {
      return next();
    }
  });
};

SOAP コネクタ

before: {req: {...}, end: ...}
after: {req: {...}, res: {...}, end: ...}

ここで、

  • req は request モジュールに渡される要求オブジェクトです。
  • res は request モジュールから返される応答オブジェクトです。