こんにちは。株式会社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に設定します。
{
"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に設定します。
{
"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
を編集します。
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, ライフサイクルフックなどを利用して制御する
ではまた次回〜。