絞り込む、並べる、ページに分ける
エントリーの一覧は、条件で絞り込み、好きな順に並べ、何件かずつに分けて取り出せます。使うのは、一覧の URL に付ける 4 つのパラメーターです。
| パラメーター | すること | 既定 |
|---|---|---|
where |
条件で絞り込む | 絞り込まない |
order |
並べる | 公開した日時の新しい順(-sys.publishedAt) |
limit |
1 回に返す数。0〜100 | 20 |
offset |
先頭から飛ばす数 | 0 |
この 4 つは一覧だけで使えます。1 件やシングルを取り出す URL に付けると、400 が返ります。
- [読み取り]の権限のある API キー。発行のしかたは API キーを作る、権限を決める にあります
- 一覧の取り出し方は エントリーを取り出す にあります
下の例では、<ホスト名> をあなたの環境のホスト名に、<API キー> を API キーに置き換えてください。コンテンツタイプ ID は「posts」、フィールド ID は「title」の例です。
絞り込む(where)
Section titled “絞り込む(where)”where には、SQL の WHERE 句に似た式を書きます。式には空白や記号が入るので、URL に入れるときはエンコードします。curl なら --data-urlencode を使います。
タイトルに「Rust」を含むエントリーに絞り込みます。
curl -G https://<ホスト名>.hakocms.net/api/v1/content/posts \ -H "Authorization: Bearer <API キー>" \ --data-urlencode 'where=title contains "Rust"'当てはまるエントリーだけが items に入り、total が当てはまる数になります。
JavaScript では、URLSearchParams がエンコードします。
const params = new URLSearchParams({ where: 'title contains "Rust" and sys.publishedAt >= "2026-10-01"',});const res = await fetch( `https://<ホスト名>.hakocms.net/api/v1/content/posts?${params}`, { headers: { Authorization: "Bearer <API キー>" } },);const { items, total } = await res.json();| やりたいこと | 書き方 |
|---|---|
| 等しい、等しくない | category = "tech"、category != "tech" |
| 大小 | price < 1000、price <= 1000、price > 0、price >= 0 |
| 日時 | sys.publishedAt >= "2026-10-01"、eventAt < "2026-10-08T09:00:00+09:00" |
| 含む、含まない | title contains "Rust"、title not contains "Rust" |
| 前方一致 | title startsWith "Rust" |
| どれかに一致、どれにも一致しない | sys.id in ("a", "b")、category not in ("pr", "ad") |
| 値がある、ない | eyecatch exists、eyecatch not exists |
| 組み合わせる | and、or、not、括弧 ( ) |
条件を組み合わせた例です。
category = "tech" and (title contains "Rust" or title contains "Go")- 文字列と日時は
"…"か'…'で囲みます。中の引用符は\"\'、\は\\と書きます - 数値と
true、falseは囲みません - 日時は、RFC 3339 か、日付だけで書きます。日付だけなら、その日の 0 時(UTC)です。比べるときは UTC にそろえます
andornotなどのキーワードは、大文字でも小文字でもかまいません- 先に結び付くのは
not、次にand、最後にorです(SQL と同じ) containsは部分一致です。%や_に特別な意味はありません!=、not contains、not in、notで否定したときは、値のないエントリーも当てはまります
ユーザーが入れた語を式に埋め込むときは、" と \ の前に \ を足してから囲んでください。そのまま埋め込むと、語の中の " で式が壊れます。
const quote = (s) => `"${s.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;const where = `title contains ${quote(keyword)}`;フィールドの種類ごとに使える演算子
Section titled “フィールドの種類ごとに使える演算子”| 対象 | 使える演算子 |
|---|---|
sys.id |
= != contains not contains startsWith in not in |
sys.createdAt sys.updatedAt sys.publishedAt sys.firstPublishedAt |
= != < <= > >= startsWith in not in |
| テキスト、テキストエリア | = != contains not contains startsWith in not in exists |
| 数値 | = != < <= > >= in not in exists |
| 日時 | = != < <= > >= startsWith in not in exists |
| 真偽値 | = != in not in。値がなければ false として比べる |
| 参照 | 参照先のエントリー ID で = != in not in exists |
| 複数参照、セレクト | = != contains not contains in not in exists。= は「その値を要素に含む」 |
| 画像、ファイル、リッチテキスト、カスタム | exists |
| 複数画像、繰り返し | exists(空でないか) |
参照先のフィールドで絞り込むこと(author.name = "Kohei" など)は、まだできません。参照先のエントリー ID で絞り込んでください(author = "kohei")。
1 つの式に書ける条件は 30 個まで、括弧と not の入れ子は 5 段まで、式の長さは 2000 文字まで、in の値は 100 個までです。URL 全体は 8 KB までで、超えると 414 が返ります。
並べる(order)
Section titled “並べる(order)”order に、並べる基準を書きます。先頭に - を付けると、大きい順(新しい順)になります。カンマで区切ると、前の基準で同じものを次の基準で並べます。
公開した日時の新しい順に並べ、同じならタイトルの順に並べます。
curl -G https://<ホスト名>.hakocms.net/api/v1/content/posts \ -H "Authorization: Bearer <API キー>" \ --data-urlencode "order=-sys.publishedAt,title"- 並べられるのは、
sys.id、sys.createdAt、sys.updatedAt、sys.publishedAt、sys.firstPublishedAtと、テキスト、テキストエリア、日時、数値のフィールドです - 文字列はバイトの順、数値は数の大きさ、日時は時刻の順に比べます
- 値のないエントリーは、どちらの向きでも後ろに並びます
- 基準がすべて同じエントリーは、新しく作った順に並びます
ページに分ける(limit と offset)
Section titled “ページに分ける(limit と offset)”limit で 1 回に返す数を、offset で先頭から飛ばす数を決めます。1 ページ 10 件の 3 ページ目(21〜30 件目)を取り出します。
curl -G https://<ホスト名>.hakocms.net/api/v1/content/posts \ -H "Authorization: Bearer <API キー>" \ -d limit=10 \ -d offset=20次のように返ります(items の中は省いています)。
{ "items": [], "total": 42, "limit": 10, "offset": 20 }total は、limit と offset で区切る前の、当てはまる全体の数です。全体のページ数は、total を limit で割って切り上げた数です。
全部のエントリーを順に取り出すときは、offset を limit ずつ増やし、total に届くまでくり返します。並びが変わらないように、order を決めておきます。
const base = "https://<ホスト名>.hakocms.net/api/v1/content/posts";const headers = { Authorization: "Bearer <API キー>" };const all = [];for (let offset = 0; ; offset += 100) { const params = new URLSearchParams({ order: "sys.createdAt", limit: "100", offset: String(offset), }); const res = await fetch(`${base}?${params}`, { headers }); const { items, total } = await res.json(); all.push(...items); if (items.length === 0 || all.length >= total) break;}console.log(all.length);1 回の応答は 5 MB までです。超えると 400 が返ります。そのときは limit を小さくするか、select で返すフィールドを減らしてください(エントリーを取り出す)。
返った total が、管理画面で同じ条件のエントリーを数えた数と同じなら、絞り込めています。
式が読めないときや、そのフィールドに使えない演算子を書いたときは、400 が返り、message に理由が出ます。式の誤りは、何文字目かも出ます。
| 式 | message |
|---|---|
title like "x" |
where: expected an operator (=, !=, <, <=, >, >=, contains, startsWith, in, exists) at character 7, found "like" |
nope = "x" |
where: unknown field "nope" |
title < "a" |
where: lt (<) cannot be used with the text field "title" |
price = "abc" |
where: "abc" is not a number ("price") |
title = 1 |
where: 1 is not a string; put it in quotes ("title") |