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

More than 1 year has passed since last update.

posted at

updated at

strapiで自動生成されるAPIのカスタマイズをする

こんにちは。株式会社dottの山上です。
普段はQiita:teamで社内向けの記事しか書いてないので若干ビクビクしておりますが、
Strapi Advent Calenderの6日目の本日は、Strapiが自動生成するAPIのカスタマイズ方法について書いて行きたいと思います。

Strapiの概要や始め方については、strapi advent calendarの以下の記事を参照お願いします!
HeadlessCMS Strapiの使いどころ
Strapi Quick Start Guide 日本語訳(こちらの記事はzennへ飛びます)

まずはモデルを作成する

こちらを参照してください。

strapiが自動生成してくれるAPI

strapiはモデルを作成すると以下6種類のAPIを自動生成してくれます。
基本的なCRUDとエントリ数のカウントをするAPIですね。

Method Path Description
GET /{content-type} {content-type}のエントリ一覧を取得する
GET /{content-type}/:id {content-type}の指定したidのエントリを取得する
GET /{content-type}/count {content-type}のエントリ数を取得する
POST /{content-type} {content-type}のエントリを作成する
DELETE /{content-type}/:id {content-type}のエントリを削除する
PUT /{content-type}/:id {content-type}の指定したidのエントリを更新する

APIのカスタマイズ

APIは、モデル定義後にプロジェクト内に自動生成される./api/{content-type}/controllers/{content-type}.jsを編集する事でカスタマイズできます。
公式ドキュメントにカスタマイズするためのベースになるコードが紹介されているので、まずはそれをコピペしてから編集していくことになります。

まずはこのrequire文でparseMultipartDataとsanitizeEntityを使えるようにします。

const { parseMultipartData, sanitizeEntity } = require('strapi-utils');

parseMultipartData: formData形式のリクエストをdata(json部分)とfiles(アップロードするファイル)に分けるメソッド
sanitizeEntity: モデルからprivate fieldとして定義したフィールドを削除するメソッド

例えば、restaurantというモデルのcreateでメールアドレスの重複をチェックして、重複していれば409エラーで返却する、という事をしたい場合は、以下のような感じです。

./api/restaurant/controllers/restaurant.js
// restaurantというモデルにemailというフィールドが存在するという前提です。
const { parseMultipartData, sanitizeEntity } = require('strapi-utils');

module.exports = {
  async create(ctx) {
    let entity;
    if (ctx.is('multipart')) {
      const { data, files } = parseMultipartData(ctx);
      if (await strapi.services.restaurant.isDuplicated(data.email)) {
        return ctx.response.conflict('duplicate email.');
      }
      entity = await strapi.services.restaurant.create(data, { files });
    } else {
      if (await strapi.services.restaurant.isDuplicated(ctx.request.body.email)) {
        return ctx.response.conflict('duplicate email.');
      }
      entity = await strapi.services.restaurant.create(ctx.request.body);
    }
    return sanitizeEntity(entity, { model: strapi.models.restaurant });
  }
}

isDuplicatedはサービス側に定義してあげるとコントローラ側の記述がスッキリするのでオススメです!

./api/restaurant/services/restaurant.js
module.exports = {
  // restaurant内に同じemailが存在する個数を数えて、1個でもあればtrueになって返却されるメソッド
  isDuplicated: async (email) => {
    return await strapi.services.restaurant.count({email}) > 0;
  }
}

まとめ

  • モデルを作るとAPIが自動生成されます、すごい!
  • 自動生成されるAPIはカスタマイズが可能。基本的なCRUD以外で何かしたいときはカスタマイズしてみましょう。
  • サービスをうまく使ってコントローラ側の処理を読みやすくしましょう!

今回は以上になります、ではまた次回!

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
4
Help us understand the problem. What are the problem?