あらかじめ Strapi Dashboard の Content-Type Builder から、Counter という Collection を追加しておきます。今回はサンプルとして名称を Counter としましたが、好きに決められます。
counter/routes/counter.ts
を以下のように書き替えます。
src/api/counter/routes/counter.ts
export default {
routes: [
{
method: `PUT`, // GET/PUT/POST/DELETE/PATCH
path: `/counters/:articleId/view`, // ルーティングパスの指定。「:articleId」は動的なルーティング
handler: `counter.increment`, // コントローラーに追加した独自の処理を指定
},
],
};
counter/controllers/counter.ts
を以下のように書き替えます。
src/api/counter/controllers/counter.ts
import { factories } from "@strapi/strapi";
interface ArticleCounter {
id: number;
view: number;
createdAt: string;
updatedAt: string;
}
interface Article {
id: number;
counter: ArticleCounter | null;
}
export default factories.createCoreController(
`api::counter.counter`,
({ strapi }) => ({
/** コントローラーに追加した独自の処理 */
increment: async (ctx) => {
// URLから記事IDを取得
const articleId = ctx.params.articleId as string; // http://localhost:1337/api/counters/:articleId/view
// 記事IDからカウンター情報を取得する
const article = (await strapi.entityService.findOne(
`api::article.article`,
articleId,
{
fields: [],
populate: { counter: true },
}
)) as Article | null;
// 記事が無ければ処理を中断
if (article === null) {
return;
}
let counter: ArticleCounter = null;
if (article.counter === null) {
// カウンターデータが無ければ、新規作成
counter = await strapi.entityService.create(
`api::counter.counter`,
{
data: {
article: articleId,
view: 1,
},
}
);
} else {
// カウンターデータがあれば、カウントアップした値で更新
counter = await strapi.entityService.update(
`api::counter.counter`,
article.counter.id,
{ data: { view: article.counter.view + 1 } }
);
}
ctx.body = { status: `OK`, counter }; // we could also send a JSON
},
})
);
ローカル環境であれば http://localhost:1337/api/counters/1234/view
に対して PUT でアクセスすると、記事 ID:1234 に対してカウントアップ処理を行います。
nuxt3 でのフロントエンドサンプル
以下、nuxt3 と @nuxtjs/strapi を使った場合のフロントからのアクセス例です。
package.json
{
"devDependencies": {
"@nuxtjs/strapi": "^1.5.0",
"nuxt": "^3.0.0-rc.6"
}
}
nuxt.config.ts
import { defineNuxtConfig } from "nuxt";
// https://v3.nuxtjs.org/docs/directory-structure/nuxt.config
export default defineNuxtConfig({
buildModules: [
// strapi
[
"@nuxtjs/strapi",
{
url: process.env?.STRAPI_URL || `http://localhost:1337`,
prefix: "/api",
version: "v4",
cookie: {},
},
],
],
});
ts
/**
* 指定した記事IDのviewカウンタをインクリメントするメソッド
*/
async function view(articleId: number) {
// strapi通信オブジェクトを取得
const strapiClient = useStrapiClient();
// API通信: 指定した記事IDのviewカウンタをインクリメントする
await strapiClient<any>(`/counters/${articleId}/view`, {
method: `PUT`,
});
}
view メソッドの引数に記事IDを渡すと、カウンターをインクリメントするカスタム API を呼び出します。