Strapi
Node.js/TypeScriptベースのオープンソースヘッドレスCMS。REST/GraphQL API提供、カスタマイズ性が高く開発者フレンドリー。
CMS
Strapi
概要
Strapiは、現代的なWebアプリケーション開発のために設計されたオープンソースのヘッドレスCMSです。
詳細
Strapi(ストラピ)は、フロントエンドとバックエンドを分離したヘッドレス(デカップルド)アーキテクチャを採用したコンテンツ管理システムです。Node.jsとKoa.jsをベースに構築され、開発者に柔軟なAPI開発環境を提供します。RESTとGraphQLの両方のAPIをサポートし、任意のフロントエンド技術(React、Vue.js、Angular、Next.js等)と組み合わせて使用できます。管理画面は直感的で使いやすく、コンテンツタイプの定義、ユーザー管理、権限設定、プラグイン管理等を視覚的に行えます。PostgreSQL、MySQL、SQLite、MariaDBをサポートし、Dockerによるデプロイメント、AWS/GCP/Azureへのクラウドデプロイにも対応しています。企業向けエンタープライズ版では、高度な権限管理、RBAC、SSO、ワークフロー機能が利用できます。
メリット・デメリット
メリット
- ヘッドレス設計: フロントエンドの選択肢が豊富で柔軟な開発が可能
- RESTとGraphQL: 両方のAPIタイプをサポート
- 自己ホスト型: オンプレミスでの完全なデータコントロール
- 直感的な管理画面: 非技術者でも操作しやすいUI
- 豊富なプラグイン: 機能拡張が容易
- オープンソース: 無料で利用でき、コミュニティが活発
- 多言語対応: 国際化機能を標準搭載
デメリット
- 自己管理: インフラ管理とメンテナンスが必要
- 学習コスト: ヘッドレス設計の理解が必要
- リソース消費: Node.jsアプリケーションとしてのサーバーリソース
- 複雑な設定: 高度なカスタマイズには技術知識が必要
- スケーラビリティ: 大規模トラフィックには追加設定が必要
主要リンク
使い方の例
インストールと初期設定
# Strapiプロジェクトの作成
npx create-strapi-app@latest my-project --quickstart
# 開発サーバーの起動
npm run develop
# 管理画面アクセス: http://localhost:1337/admin
コンテンツタイプの定義
// config/api/article/models/article.settings.json
{
"kind": "collectionType",
"collectionName": "articles",
"info": {
"name": "article"
},
"options": {
"increments": true,
"timestamps": true
},
"attributes": {
"title": {
"type": "string",
"required": true
},
"content": {
"type": "richtext"
},
"author": {
"type": "relation",
"relation": "manyToOne",
"target": "plugin::users-permissions.user"
},
"published_at": {
"type": "datetime"
},
"slug": {
"type": "uid",
"targetField": "title"
}
}
}
API の利用
// REST APIでのデータ取得
const response = await fetch('http://localhost:1337/api/articles');
const data = await response.json();
// GraphQLでのデータ取得
const ARTICLES_QUERY = `
query GetArticles {
articles {
data {
id
attributes {
title
content
published_at
author {
data {
attributes {
username
}
}
}
}
}
}
}
`;
const response = await fetch('http://localhost:1337/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query: ARTICLES_QUERY }),
});
カスタムAPIエンドポイント
// api/article/controllers/article.js
'use strict';
const { createCoreController } = require('@strapi/strapi').factories;
module.exports = createCoreController('api::article.article', ({ strapi }) => ({
// カスタムエンドポイント
async findPublished(ctx) {
const entries = await strapi.entityService.findMany('api::article.article', {
filters: {
published_at: {
$notNull: true,
},
},
populate: {
author: true,
},
});
return entries;
},
// 人気記事の取得
async findPopular(ctx) {
const entries = await strapi.entityService.findMany('api::article.article', {
sort: { views: 'desc' },
limit: 10,
});
return entries;
}
}));
プラグインの作成
// plugins/custom-plugin/server/controllers/my-controller.js
'use strict';
module.exports = {
index(ctx) {
ctx.body = strapi
.plugin('custom-plugin')
.service('myService')
.getWelcomeMessage();
},
};
// plugins/custom-plugin/server/services/my-service.js
'use strict';
module.exports = {
getWelcomeMessage() {
return 'Welcome to Strapi 🚀';
},
};
Docker設定
# Dockerfile
FROM node:18-alpine
WORKDIR /opt/app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 1337
CMD ["npm", "start"]
# docker-compose.yml
version: '3'
services:
strapi:
container_name: strapi
build: .
image: strapi:latest
restart: unless-stopped
env_file: .env
environment:
DATABASE_CLIENT: postgres
DATABASE_HOST: strapiDB
DATABASE_PORT: 5432
DATABASE_NAME: strapi
DATABASE_USERNAME: strapi
DATABASE_PASSWORD: strapi
ports:
- '1337:1337'
networks:
- strapi
depends_on:
- strapiDB
strapiDB:
container_name: strapiDB
platform: linux/amd64
restart: unless-stopped
env_file: .env
image: postgres:14.5-alpine
environment:
POSTGRES_USER: strapi
POSTGRES_PASSWORD: strapi
POSTGRES_DB: strapi
ports:
- '5432:5432'
networks:
- strapi
networks:
strapi:
name: Strapi
driver: bridge