0
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

strapiのGETで関連テーブルのデータ取得を制御する方法

こんにちは。株式会社dottの山上です。
Strapi Advent Calenderの11日目の本日は、strapiのGETメソッドでのリレーションしているテーブルのデータの取得方法について書いて行きたいと思います。

Strapi Advent Calenderのその他の記事はこちら

デフォルトの挙動

テスト用に、Contents type builderで以下のようなモデルを作成します。

baseModel: emailを持っていて、relationalModelに1:1のリレーションが張られている
relationalModel: name, summaryを持っていて、baseModelに1:1のリレーションが張られている

この状態でbaseModelをGETすると、デフォルトではrelationalModelのデータは自動で展開された状態でGETされます。

こんな感じでリクエストすると、

curl --location --request GET 'http://localhost:1337/base-models' \
--header 'Authorization: Bearer {token}'

レスポンスはこんな感じで帰ってきます。

[
    {
        "id": 1,
        "email": "test@example.com",
        "relational_model": {
            "id": 1,
            "summary": "関連テーブルのデータです",
            "name": "テストさん",
            "base_model": 1,
            "created_by": 1,
            "updated_by": 1,
            "created_at": "2020-12-10T07:44:21.424Z",
            "updated_at": "2020-12-10T07:44:36.100Z"
        },
        "created_by": {
            "id": 1,
            "firstname": "user",
            "lastname": "test",
            "username": null
        },
        "updated_by": {
            "id": 1,
            "firstname": "user",
            "lastname": "test",
            "username": null
        },
        "created_at": "2020-12-10T07:44:36.093Z",
        "updated_at": "2020-12-10T07:44:36.111Z"
    }
]

settings.jsonから設定する

常に同じ項目に対して同じ制御になるのであれば、/api/{model-name}/models/{model-name}.settings.jsonを手動で編集することで、データ取得の制御が可能です。

1. privateをtrueに設定する

relational_modelの、privateをtrueに設定します。

/api/base-model/models/base-model.settings.json
{
  "kind": "collectionType",
  "collectionName": "base_models",
  "info": {
    "name": "baseModel"
  },
  "options": {
    "increments": true,
    "timestamps": true
  },
  "attributes": {
    "email": {
      "type": "email"
    },
    "relational_model": {
      "model": "relational-model",
      "via": "base_model",
      "private": true
    }
  }
}

その場合は、以下のように、relational_modelと言う項目そのものが返却されません。

[
    {
        "id": 1,
        "email": "test@example.com",
        "created_by": {
            "id": 1,
            "firstname": "user",
            "lastname": "test",
            "username": null
        },
        "updated_by": {
            "id": 1,
            "firstname": "user",
            "lastname": "test",
            "username": null
        },
        "created_at": "2020-12-10T07:44:36.093Z",
        "updated_at": "2020-12-10T07:44:36.111Z"
    }
]

2.autoPopulateをfalseに設定する

relational_modelの、autoPopulateをfalseに設定します。

/api/base-model/models/base-model.settings.json
{
  "kind": "collectionType",
  "collectionName": "base_models",
  "info": {
    "name": "baseModel"
  },
  "options": {
    "increments": true,
    "timestamps": true
  },
  "attributes": {
    "email": {
      "type": "email"
    },
    "relational_model": {
      "model": "relational-model",
      "via": "base_model",
      "autoPopulate": false
    }
  }
}

こっちの場合は、以下のように、relational_modelと言う項目そのものは返却されますが、ID以外は返却されません。

[
    {
        "id": 1,
        "email": "test@example.com",
        "relational_model": 1,
        "created_by": {
            "id": 1,
            "firstname": "user",
            "lastname": "test",
            "username": null
        },
        "updated_by": {
            "id": 1,
            "firstname": "user",
            "lastname": "test",
            "username": null
        },
        "created_at": "2020-12-10T07:44:36.093Z",
        "updated_at": "2020-12-10T07:44:36.111Z"
    }
]

jsで制御する

動的に制御したい場合はライフサイクルフックが用意されているので、そちらを利用します。
/api/{model-name}/models/{model-name}.jsを編集します。

/api/base-model/models/base-model.js
module.exports = {
  lifecycles: {
    async afterFind(results, params, populate) {
      // ユーザーの権限などなんらかの条件で分岐させる
      if ('何かの条件') {
        // relational_modelを削除する場合はこんな感じ
        // この場合はprivate設定と同じ結果になる
        results.map(result => {
          delete result.relational_model;
        })
      }
    }
  }
};

reference

https://strapi.io/documentation/v3.x/concepts/models.html#define-the-attributes
https://strapi.io/documentation/v3.x/concepts/models.html#lifecycle-hooks

まとめ

  • strapiは特に何もしなくてもリレーションしているテーブルのデータを引っ張ってこられる
  • もし引っ張って来たくない場合は、private, autoPopulate, ライフサイクルフックなどを利用して制御する

ではまた次回〜。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
0
Help us understand the problem. What are the problem?