kuroco-api-content

Kuroco API設計・実装およびコンテンツ管理(CRUD操作)のベストプラクティス。使用キーワード:「Kuroco API」「エンドポイント設定」「API設計」「認証」「CORS」「APIセキュリティ」「ログインAPI」「トークン認証」「Cookie認証」「JWT」「StaticToken」「X-RCMS-API-ACCESS-TOKEN」「rcms-api」「g.kuroco.app」「流量制限」「レート制限」「キャッシュ」「credentials include」「fetch」「axios」「HTTPリクエスト」「401エラー」「403エラー」「429エラー」「認証エラー」「権限エラー」「APIレスポンス」「pageInfo」「ページネーション」「アクセストークン」「リフレッシュトークン」「grant_token」「コンテンツ定義」「記事管理」「Topics」「TopicsGroup」「カテゴリ」「WYSIWYG」「ファイルアップロード」「CSVインポート」「コンテンツAPI」「拡張項目」「ext_col」「topics_id」「subject」「contents」「ymd」「topics_flg」「フィルター」「filter」「order_by」「一覧取得」「詳細取得」「list」「details」「insert」「update」「delete」「bulk_upsert」「一括更新」「タグ」「tag」「予約投稿」「open_ymd」「close_ymd」「公開設定」「閲覧制限」「関連コンテンツ」「pageID」「cnt」。APIの設計、呼び出し、認証、エラー処理、コンテンツの作成・取得・更新・削除・フィルタリングに関する質問で使用。

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "kuroco-api-content" with this command: npx skills add diverta/kuroco-skills/diverta-kuroco-skills-kuroco-api-content

Kuroco API連携 & コンテンツ管理

Kuroco HeadlessCMSのAPI設計・実装およびコンテンツ管理に関するベストプラクティス。

ドキュメント参照: /kuroco-docs スキルを使用してKuroco公式ドキュメントを検索・参照できます。

目次

Part 1: API連携パターン

Part 2: コンテンツ管理パターン


Part 1: API連携パターン

エンドポイント設計

基本構造

KurocoのAPIパスは以下の形式:

https://{サイトキー}.g.kuroco.app/rcms-api/{api_id}/{endpoint_path}

例:

https://example.g.kuroco.app/rcms-api/1/news
https://example.g.kuroco.app/rcms-api/1/member/login

エンドポイント設定の主要項目

項目説明
パスエンドポイントのURLnews, member/list
モデル操作対象Topics, Member, InquiryForm
オペレーション操作種別list, details, insert, update, delete
キャッシュレスポンスキャッシュ期間86400(1日)
流量制限リクエスト数制限100回/分
認証必須ログイン必須かどうかtrue/false

主要カテゴリとモデル

認証(Authentication)

オペレーション説明メソッド
login_challengeログインPOST
tokenアクセストークン取得POST
logoutログアウトPOST
profileログインユーザー情報取得GET
reminderパスワードリマインダーPOST

コンテンツ(Topics)

オペレーション説明メソッド
list一覧取得GET
details詳細取得GET
insert新規追加POST
update更新POST
delete削除POST
bulk_upsert一括更新POST

メンバー(Member)

オペレーション説明メソッド
listメンバー一覧GET
detailsメンバー詳細GET
insertメンバー登録POST
updateメンバー更新POST

フォーム(InquiryMessage/InquiryForm)

オペレーション説明メソッド
sendフォーム送信POST
list回答一覧GET
details回答詳細GET

セキュリティ設定

詳細リファレンス: セキュリティ設定の詳細は references/security-settings.md を参照してください。

公式ドキュメント: 詳細な公式情報は ../kuroco-docs/docs/management/api-security.md 等を参照してください。

認証方式

管理画面: [API] → [セキュリティ] で4種類から選択。

認証方式用途ヘッダー
なし開発・テスト用(本番非推奨)不要
静的アクセストークンサーバー間通信、公開APIX-RCMS-API-ACCESS-TOKEN: {固定トークン}
動的アクセストークンログイン必須サイト(JWT)X-RCMS-API-ACCESS-TOKEN: {動的トークン}
Cookieログイン必須Webサイトcredentials: 'include'(フロントエンド側)

1. Cookie認証(Webアプリ推奨)

セッションベースの認証。credentials: 'include' が必須。

// ログイン
const response = await fetch('https://example.g.kuroco.app/rcms-api/1/login', {
  method: 'POST',
  credentials: 'include',  // 必須
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    email: 'user@example.com',
    password: 'password123'
  })
})

// レスポンス例
// {
//   "grant_token": "xxxxx",
//   "status": 0,
//   "member_id": 123
// }

注意点:

  • サードパーティCookie問題(Safari等でブロックされる)
  • APIドメインとフロントエンドを**同一ドメイン(サブドメイン違い)**に設定が必要(ファーストパーティCookie化)
    • 例: api.example.comwww.example.com
  • Cookie認証APIが複数ある場合、各API間で認証状態が共有される

2. トークン認証(モバイルアプリ推奨)

JWTベースの認証。ヘッダーにトークンを付与。

// トークン取得
const tokenResponse = await fetch('https://example.g.kuroco.app/rcms-api/1/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    email: 'user@example.com',
    password: 'password123'
  })
})

const { access_token, refresh_token } = await tokenResponse.json()

// レスポンス例
// {
//   "access_token": {
//     "value": "eyJhbGciOiJS...",
//     "expiresAt": "2024-01-01T12:00:00+09:00"
//   },
//   "refresh_token": {
//     "value": "xxxxxx",
//     "expiresAt": "2024-01-08T12:00:00+09:00"
//   }
// }

// API呼び出し時
const response = await fetch('https://example.g.kuroco.app/rcms-api/1/news', {
  headers: {
    'X-RCMS-API-ACCESS-TOKEN': access_token.value
  }
})

前提条件: ユーザー1人以上、login_challenge + token エンドポイント必須。トークン認証APIが複数ある場合、各API間で認証状態は共有されない

3. StaticToken認証(サーバー間通信)

固定トークンによるAPIアクセス制限。

const response = await fetch('https://example.g.kuroco.app/rcms-api/1/internal-api', {
  headers: {
    'X-RCMS-API-ACCESS-TOKEN': 'your-static-token-here'
  }
})

設定場所: 管理画面 → API → セキュリティ → StaticToken

注意: 静的トークンはフロントエンドに組み込まれるとユーザーに見える。流出時のトークン更新を想定した運用が必要。

IPアドレス制限

管理画面: [API] → [セキュリティ] → [IPアドレス制限]

指定されたIPアドレスからのアクセスのみ許可します。

指定形式説明
個別IP192.0.2.1単一IPアドレス
CIDR192.0.2.0/24サブネット単位
範囲指定192.0.2.1-192.0.2.2ハイフンによるIP範囲

IPアドレスグループ: 定数機能で IPSETS_* を定義し、[[IPSETS_*]] で参照可能(../kuroco-docs/docs/faq/is-it-possible-to-set-multiple-ip-addresses-at-once.mdx 参照)。

CORS設定

管理画面: [API] → [セキュリティ] → [CORS]

項目対応ヘッダー説明
CORS_ALLOW_ORIGINSAccess-Control-Allow-Origin許可オリジン(ワイルドカード*は非推奨
CORS_ALLOW_METHODSAccess-Control-Allow-Methods許可HTTPメソッド
CORS_ALLOW_HEADERSAccess-Control-Allow-Headers許可リクエストヘッダー
CORS_MAX_AGEAccess-Control-Max-Ageプリフライトキャッシュ秒数
CORS_ALLOW_CREDENTIALSAccess-Control-Allow-CredentialsCookie送信の許可

CSRF対策: CORS + Content-Type: application/json でモダンブラウザでのCSRF攻撃を防御。ワイルドカードを使うと防御効果がなくなるため、必ず特定ドメインを指定すること。

変更反映の遅延: CORS設定変更後は CORS_MAX_AGE 分だけブラウザにキャッシュされる。即時反映にはブラウザキャッシュクリアまたは CORS_MAX_AGE0 に設定。

APIリクエスト制限

制限タイプ説明
None制限なし
GroupAuthログインユーザーのグループ権限をチェックし、合致した場合のみ許可
MemberCustomSearchAuthログインユーザーがカスタムメンバーフィルターの条件に合致する場合のみ許可

閲覧制限の優先順序

コンテンツ返却時の制限は以下の順序で評価されます(上位優先):

  1. API → IPアドレス制限(API全体)
  2. エンドポイント → APIリクエスト制限(エンドポイント単位)
  3. コンテンツ定義 → APIリクエスト制限
  4. コンテンツカテゴリ → APIリクエスト制限
  5. 個別コンテンツ → APIリクエスト制限

後処理によるレスポンス制限

管理画面: [API] → エンドポイント → [後処理]

APIレスポンスから不要なフィールドを除外し、公開情報を制御:

処理タイプ説明
出力許可リスト指定フィールドのみ返す(ホワイトリスト)。例: list.subject, pageInfo
出力変換リストフィールドの削除・名称変更・変換関数の適用
カスタム処理Smartyテンプレートでの独自ロジック

パフォーマンスTip: 出力許可リストは他の処理の前に配置するとSQLレベルで効果あり。

プラットフォームセキュリティ

Kurocoプラットフォームが提供するインフラレベルのセキュリティ:

  • 通信: HTTPS完全暗号化、TLS証明書自動管理
  • 防御: WAF、CDN、DDoS対策(オプションでFastly DDoS Protection)
  • 認証連携: SAML/OAuth外部ログイン、クライアント証明書(オプション)
  • 監査: アクセスログ、アプリケーションログ
  • 認定: ISMS (ISO 27001)、ISMSクラウド (ISO 27017)、プライバシーマーク
  • 診断: 毎日のコンテナ脆弱性スキャン、VADDY連携自動診断

管理API(admin_api)による設定変更

APIのセキュリティ設定は管理画面だけでなく、管理API経由でも操作可能です。/kuroco-admin-api スキルを使用してCLI経由で管理APIを実行できます。

キャッシュ戦略

推奨設定

ユースケースキャッシュ期間設定値
静的コンテンツ(ニュース等)1日86400
更新頻度低いコンテンツ1週間604800
リアルタイム性が必要キャッシュなし0
認証が必要なAPIキャッシュなし0

重要: コンテンツ・メンバー等のデータ更新時、キャッシュは自動クリアされます。

キャッシュヘッダー

レスポンスヘッダーで確認可能:

Cache-Control: max-age=86400

流量制限

レスポンスヘッダー

x-rcms-ratelimit-limit: 100      # 制限数
x-rcms-ratelimit-remaining: 95   # 残りリクエスト数
x-rcms-ratelimit-reset: 60       # リセットまでの秒数

429エラー時の対応

const response = await fetch(url)

if (response.status === 429) {
  const resetTime = response.headers.get('x-rcms-ratelimit-reset')
  throw new Error(`流量制限超過。${resetTime}秒後に再試行してください`)
}

API呼び出しパターン

一覧取得(ページネーション付き)

async function fetchNewsList(page = 1, perPage = 10) {
  const params = new URLSearchParams({
    pageID: page,
    cnt: perPage
  })

  const response = await fetch(
    `https://example.g.kuroco.app/rcms-api/1/news?${params}`,
    { credentials: 'include' }
  )

  const data = await response.json()

  // レスポンス構造
  // {
  //   "list": [...],
  //   "pageInfo": {
  //     "totalCnt": 100,
  //     "perPage": 10,
  //     "totalPageCnt": 10,
  //     "pageNo": 1
  //   }
  // }

  return data
}

フィルター検索

// filter パラメータで検索
const params = new URLSearchParams({
  filter: 'subject contains "重要"',
  order_by: 'ymd desc'
})

const response = await fetch(
  `https://example.g.kuroco.app/rcms-api/1/news?${params}`,
  { credentials: 'include' }
)

詳細取得

async function fetchNewsDetail(topicsId) {
  const response = await fetch(
    `https://example.g.kuroco.app/rcms-api/1/newsdetail/${topicsId}`,
    { credentials: 'include' }
  )

  const data = await response.json()

  // レスポンス構造
  // {
  //   "details": {
  //     "topics_id": 1,
  //     "subject": "タイトル",
  //     "contents": "<p>本文</p>",
  //     ...
  //   }
  // }

  return data.details
}

コンテンツ作成

async function createNews(newsData) {
  const response = await fetch(
    'https://example.g.kuroco.app/rcms-api/1/news/insert',
    {
      method: 'POST',
      credentials: 'include',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        subject: newsData.title,
        contents: newsData.body,
        ymd: newsData.date,
        topics_flg: 1  // 1: 公開, 0: 非公開
      })
    }
  )

  return response.json()
}

エラーハンドリング

主要エラーコード

コード説明対応
400リクエストエラーリクエストパラメータを確認
401認証エラーログイン状態・トークンを確認
403権限エラーAPIの権限設定を確認
404リソース未存在パス・IDを確認
429流量制限超過リトライまで待機
500サーバーエラーKurocoサポートに連絡

エラーレスポンス例

{
  "errors": [
    {
      "code": "authentication_error",
      "message": "ログインが必要です"
    }
  ]
}

エラーハンドリング実装

async function apiRequest(url, options = {}) {
  const response = await fetch(url, {
    credentials: 'include',
    ...options
  })

  if (!response.ok) {
    const errorData = await response.json()

    switch (response.status) {
      case 401:
        throw new Error('認証が必要です')
      case 403:
        throw new Error('アクセス権限がありません')
      case 429:
        throw new Error('リクエスト制限を超えました')
      default:
        throw new Error(errorData.errors?.[0]?.message || 'APIエラー')
    }
  }

  return response.json()
}

Part 2: コンテンツ管理パターン

コンテンツ構造

階層構造

コンテンツ定義(TopicsGroup)
├── カテゴリ(TopicsCategory)
│   └── コンテンツ(Topics)
└── 拡張項目(ext_col_01〜ext_col_XX)

コンテンツ定義の設定

管理画面: [コンテンツ定義] → [新規作成]

項目説明
グループ名コンテンツ定義の名前
識別子ユニークなID(英数字)
本文の入力方法WYSIWYG、マークダウン、HTML
閲覧制限全員/グループ制限/カスタム検索
編集制限全員/グループ制限/カスタム検索
拡張項目カスタムフィールド(最大99個)

拡張項目(カスタムフィールド)

タイプ説明APIレスポンス例
テキスト1行テキスト"ext_col_01": "値"
テキストエリア複数行テキスト"ext_col_02": "複数行\nテキスト"
WYSIWYGリッチテキスト"ext_col_03": "<p>HTML</p>"
数値整数・小数"ext_col_04": 100
日付日付選択"ext_col_05": "2024-01-01"
選択(単一)ラジオボタン"ext_col_06": "選択肢1"
選択(複数)チェックボックス"ext_col_07": ["選択肢1", "選択肢2"]
ファイル/画像アップロード"ext_col_08": { "id": "xxx", "url": "https://...", "desc": "" }
リンクURLリンク"ext_col_10": { "url": "https://...", "title": "リンク名" }
関連コンテンツ他コンテンツ参照"ext_col_11": { "topics_id": 123, "subject": "タイトル" }

Topics API オペレーション

オペレーション説明メソッドパス例
list一覧取得GET/news
details詳細取得GET/newsdetail/{topics_id}
insert新規追加POST/news/insert
update更新POST/news/update/{topics_id}
delete削除POST/news/delete/{topics_id}
bulk_upsert一括更新POST/news/bulk

コンテンツCRUD操作

一覧取得レスポンス

{
  "list": [
    {
      "topics_id": 1,
      "subject": "タイトル",
      "contents": "本文(HTML)",
      "ymd": "2024-01-01",
      "topics_flg": 1,
      "category_id": 1,
      "ext_col_01": "拡張項目値",
      "tag": ["タグ1", "タグ2"]
    }
  ],
  "pageInfo": {
    "totalCnt": 100,
    "perPage": 10,
    "totalPageCnt": 10,
    "pageNo": 1
  }
}

コンテンツ作成

const response = await fetch('/rcms-api/1/news/insert', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    subject: 'タイトル',
    contents: '<p>本文</p>',
    ymd: '2024-01-01',
    topics_flg: 1,           // 1: 公開, 0: 非公開
    category_id: 1,
    open_ymd: '2024-12-01',  // 予約公開開始日
    close_ymd: '2024-12-31', // 公開終了日
    tag: ['タグ1', 'タグ2'],
    ext_col_01: 'カスタム値'
  })
})

コンテンツ更新

const response = await fetch(`/rcms-api/1/news/update/${topicsId}`, {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    subject: '更新タイトル',
    contents: '更新本文'
    // 更新したいフィールドのみ送信可能
  })
})

コンテンツ削除

await fetch(`/rcms-api/1/news/delete/${topicsId}`, {
  method: 'POST',
  credentials: 'include'
})

フィルタークエリ

基本構文: filter={field} {operator} {value}

演算子
=, !=filter=category_id = 1
>, >=, <, <=filter=ymd >= '2024-01-01'
containsfilter=subject contains 'キーワード'
in, not_infilter=category_id in [1, 2, 3]

複合条件: filter=(category_id = 1 or category_id = 2) and topics_flg = 1

ソート: order_by=ymd desc

詳細な使い方: references/filter-query.md を参照

ファイル・CSV操作

ファイルアップロード

// 1. ファイルアップロード
const formData = new FormData()
formData.append('file', file)
const result = await fetch('/rcms-api/1/files/upload', {
  method: 'POST',
  credentials: 'include',
  body: formData
})
const { file_id } = await result.json()

// 2. コンテンツに紐付け
await fetch('/rcms-api/1/news/insert', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    subject: 'タイトル',
    ext_col_02: { file_id, desc: '説明' }
  })
})

詳細(一括更新、カテゴリ、タグ、閲覧制限): references/file-operations.md を参照

管理API(admin_api)によるコンテンツ操作

/kuroco-admin-api スキルを使うと、管理画面と同等のコンテンツ操作をCLI経由で実行できます。フロントエンドAPI(rcms-api)との違いに注意してください。

フロントエンドAPI vs 管理API

項目フロントエンドAPI(rcms-api)管理API(admin_api)
対象エンドユーザー管理者・運用者
認証StaticToken / DynamicToken / Cookie管理画面セッションCookie
エンドポイント/rcms-api/{api_id}/{path}/direct/rcms_api/admin_api/
利用場面フロントエンド実装データ一括操作、構造確認、設定変更

コンテンツ定義一覧の取得

# admin_api: コンテンツ定義(TopicsGroup)一覧(columnsで必要カラムのみ取得)
kuroco-admin exec topics/topics_group_list --columns topics_group_id,group_nm --json

コンテンツ一覧の取得

# admin_api: 特定コンテンツ定義のコンテンツ一覧(columnsで必要カラムのみ取得)
kuroco-admin exec topics/topics_list --param "topics_group_id[]=1" --param cnt=10 --columns topics_id,subject,ymd --json

コンテンツの作成

# admin_api: コンテンツ作成(※実行前にユーザー確認必須)
kuroco-admin exec topics/topics_edit --MODE INSERT --data '{"subject":"タイトル","contents":"本文","topics_group_id":1,"topics_flg":1}' --json

活用シーン

  • サイト構造の把握: コンテンツ定義一覧・拡張項目の確認
  • データの一括確認・修正: 管理画面GUIを経由せず効率的にデータ操作
  • スキーマ確認: kuroco-admin help topics/topics_edit --json でフィールド定義を取得

注意: insert/update/deleteは必ずユーザーに確認してから実行すること。詳細は /kuroco-admin-api スキル参照。

ベストプラクティス

  • キャッシュ活用: エンドポイント設定で キャッシュ: 86400(1日)を設定。更新時は自動クリア
  • ページネーション: pageIDcnt パラメータで分割取得

関連スキル

  • /kuroco-frontend-integration - Nuxt.js/Next.jsでのAPI呼び出しパターン、AI自動デプロイ
  • /kuroco-server-processing - Smartyプラグイン・構文リファレンス、Webhook・バッチ処理
  • /kuroco-admin-api - 管理API(admin_api)の操作

関連ドキュメント

スキル内リファレンス

Kuroco公式ドキュメント

  • ../kuroco-docs/docs/management/api-security.md - APIセキュリティ設定(認証方式、IP制限)
  • ../kuroco-docs/docs/management/api-list.md - API一覧・CORS設定
  • ../kuroco-docs/docs/management/api-postprocessing.md - API後処理の設定
  • ../kuroco-docs/docs/reference/endpoint-settings.md - エンドポイント設定項目一覧
  • ../kuroco-docs/docs/reference/post-processing.md - 後処理の詳細リファレンス
  • ../kuroco-docs/docs/tutorials/configure-endpoint.md - エンドポイント設定方法
  • ../kuroco-docs/docs/tutorials/login.md - ログイン実装
  • ../kuroco-docs/docs/tutorials/restricting-api-access-with-statictoken.md - StaticToken認証
  • ../kuroco-docs/docs/reference/api-cache.md - APIキャッシュ
  • ../kuroco-docs/docs/reference/filter-query.md - フィルタークエリ
  • ../kuroco-docs/docs/about/security.md - プラットフォームセキュリティ概要
  • ../kuroco-docs/docs/faq/in-what-order-are-viewing-restrictions-applied.mdx - 閲覧制限の優先順序
  • ../kuroco-docs/docs/faq/cors-and-content-type-prevent-csrf-attacks.mdx - CSRF対策
  • ../kuroco-docs/docs/faq/the-api-returns-403-forbidden-even-though-no-restrictions-are-applied.mdx - 403エラーの解決
  • ../kuroco-docs/docs/tutorials/adding-a-topics.md - コンテンツ定義作成
  • ../kuroco-docs/docs/tutorials/bulk-upload-in-csv.md - CSVアップロード
  • ../kuroco-docs/docs/management/content-structure-topics.md - コンテンツ構造

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

kuroco-docs

No summary provided by upstream source.

Repository SourceNeeds Review
General

kuroco-frontend-integration

No summary provided by upstream source.

Repository SourceNeeds Review
General

kuroco-server-processing

No summary provided by upstream source.

Repository SourceNeeds Review
General

kuroco-webhook-processing

No summary provided by upstream source.

Repository SourceNeeds Review