[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article:cybozu-kintone-api-design":3},{"meta":4,"markdown":117},{"type":5,"articleId":6,"slug":7,"title":8,"titleEn":9,"category":10,"summary":11,"publishedAt":12,"image":13,"vocabulary":14},"article","tech-cybozu-kintone-api","cybozu-kintone-api-design","kintone API設計の十年 — 後方互換性との戦い","A Decade of kintone API Design — The Battle for Backward Compatibility","tech","Cybozu's kintone REST API design philosophy across a decade — versioning strategy, deprecation lifecycle, customer-driven extension model (plugins, customize), and preserving backward compatibility through careful schema evolution.\n","2026-04-27T00:00:00Z","https:\u002F\u002Fimages.yamiyomi.com\u002Ftech-cybozu-kintone-api.png",[15,20,25,29,33,37,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113],{"word":16,"reading":17,"meaning":18,"level":19},"設計","せっけい","design","N2",{"word":21,"reading":22,"meaning":23,"level":24},"互換性","ごかんせい","compatibility","N1",{"word":26,"reading":27,"meaning":28,"level":19},"後方","こうほう","backward",{"word":30,"reading":31,"meaning":32,"level":19},"戦い","たたかい","battle",{"word":34,"reading":35,"meaning":36,"level":19},"拡張","かくちょう","extension",{"word":38,"reading":39,"meaning":40,"level":24},"廃止","はいし","deprecation",{"word":42,"reading":43,"meaning":44,"level":19},"段階","だんかい","stage\u002Fphase",{"word":46,"reading":47,"meaning":48,"level":24},"周知","しゅうち","announcement",{"word":50,"reading":51,"meaning":52,"level":19},"期間","きかん","period",{"word":54,"reading":55,"meaning":56,"level":24},"設計思想","せっけいしそう","design philosophy",{"word":58,"reading":59,"meaning":60,"level":19},"顧客","こきゃく","customer",{"word":62,"reading":63,"meaning":64,"level":19},"業務","ぎょうむ","business operations",{"word":66,"reading":67,"meaning":68,"level":19},"業務アプリ","ぎょうむあぷり","business app",{"word":70,"reading":71,"meaning":72,"level":19},"進化","しんか","evolution",{"word":74,"reading":75,"meaning":76,"level":19},"影響","えいきょう","impact",{"word":78,"reading":79,"meaning":80,"level":19},"既存","きそん","existing",{"word":82,"reading":83,"meaning":84,"level":19},"維持","いじ","maintain",{"word":86,"reading":87,"meaning":88,"level":19},"追加","ついか","addition",{"word":90,"reading":91,"meaning":92,"level":19},"削除","さくじょ","deletion",{"word":94,"reading":95,"meaning":96,"level":24},"置換","ちかん","replacement",{"word":98,"reading":99,"meaning":100,"level":19},"安定","あんてい","stable",{"word":102,"reading":103,"meaning":104,"level":19},"契約","けいやく","contract",{"word":106,"reading":107,"meaning":108,"level":19},"保証","ほしょう","guarantee",{"word":110,"reading":111,"meaning":112,"level":19},"動作","どうさ","behavior",{"word":114,"reading":115,"meaning":116,"level":19},"検証","けんしょう","verification","\n::para\n[サイボウズ]{さいぼうず:Cybozu}の[業務]{ぎょうむ:business operations:N3}アプリプラットフォーム「[kintone]{きんとーん:kintone}」は[2011]{にせんじゅういち:2011}[年]{ねん:year:N5}のリリース[以来]{いらい:since:N4}、[十数年]{じゅうすうねん:over ten years:N3}にわたって[同じ]{おなじ:same:N4}REST APIを[進化]{しんか:evolve:N3}させ[続けて]{つづけて:continuing:N3}きました。[一度]{いちど:once:N4}[公開]{こうかい:published:N4}したAPIは[何]{なん:how many:N5}[万]{まん:ten thousand:N5}もの[顧客]{こきゃく:customer:N1}の[業務]{ぎょうむ:business:N3}を[支えて]{ささえて:to support:N3}おり、[安易]{あんい:thoughtless:N3}な[変更]{へんこう:change:N3}は[許され]{ゆるされ:permitted:N3}ません。[本]{ほん:this:N5}[記事]{きじ:article:N3}では、[後方]{こうほう:backward:N4}[互換性]{ごかんせい:compatibility:N2}を[守り]{まもり:protecting:N3}ながらAPIを[進化]{しんか:evolve:N3}させてきた[設計]{せっけい:design:N2}[思想]{しそう:philosophy:N3}を[整理]{せいり:organize:N1}します。\n\n#en\nCybozu's business app platform \"kintone\" has continued evolving the same REST API for over ten years since its 2011 release. Once published, an API supports the operations of tens of thousands of customers, and thoughtless changes are not permitted. This article organizes the design philosophy of evolving the API while preserving backward compatibility.\n::\n\n::heading\n[追加]{ついか:addition:N3}は[歓迎]{かんげい:welcomed:N1}、[削除]{さくじょ:deletion:N1}は[最後]{さいご:last:N3}の[手段]{しゅだん:resort:N3}\n\n#en\nAdditions Are Welcome; Deletions Are a Last Resort\n::\n\n::para\nAPIの[後方]{こうほう:backward:N4}[互換性]{ごかんせい:compatibility:N2}を[守る]{まもる:to protect:N3}ための[基本]{きほん:basic:N1}[原則]{げんそく:principle:N2}は「[既存]{きそん:existing:N1}フィールドを[変えない]{かえない:not change:N3}」「[新しい]{あたらしい:new:N4}フィールドは[追加]{ついか:add:N3}してよい」「[削除]{さくじょ:deletion:N1}は[最終]{さいしゅう:final:N3}[手段]{しゅだん:resort:N3}」です。[kintone]{きんとーん:kintone}ではレスポンスJSONに[新規]{しんき:new:N3}フィールドを[加える]{くわえる:to add:N3}[際]{さい:occasion:N3}も、[既存]{きそん:existing:N1}クライアントが[未知]{みち:unknown:N3}のフィールドを[無視]{むし:ignore:N1}して[動作]{どうさ:operate:N4}し[続ける]{つづける:to continue:N3}ことを[前提]{ぜんてい:premise:N1}に[設計]{せっけい:design:N2}しています。\n\n#en\nThe basic principles of preserving backward compatibility are: \"do not change existing fields,\" \"new fields may be added,\" and \"deletion is a last resort.\" When kintone adds new fields to response JSON, it does so on the premise that existing clients continue operating by ignoring unknown fields.\n::\n\n::callout\nAPIの[契約]{けいやく:contract:N1}は[一度]{いちど:once:N4}[公開]{こうかい:published:N4}したら[基本的に]{きほんてきに:basically:N1}[永遠]{えいえん:forever:N2}と[考える]{かんがえる:to think:N4}べきです。[壊す]{こわす:to break:N1}には[壊す]{こわす:to break:N1}だけの[理由]{りゆう:reason:N3}と[手順]{てじゅん:procedure:N2}が[必要]{ひつよう:required:N3}です。\n\n#en\nYou should treat an API contract as basically forever once published. Breaking it requires both a reason for breaking and a proper procedure.\n::\n\n::heading\nバージョン[戦略]{せんりゃく:strategy:N2}\n\n#en\nVersioning Strategy\n::\n\n::para\n[kintone]{きんとーん:kintone}のAPIはURLパスに[明示的]{めいじてき:explicit:N3}な[大]{だい:major:N5}バージョンを[持た]{もた:hold:N4}せず、[一]{ひと:one:N5}つの[安定]{あんてい:stable:N3}した[契約]{けいやく:contract:N1}を[長期]{ちょうき:long-term:N3}にわたって[維持]{いじ:maintain:N1}する[方針]{ほうしん:policy:N2}を[採って]{とって:to take:N2}きました。これは「v2、v3とバージョンを[増やす]{ふやす:to increase:N3}とクライアント[実装]{じっそう:implementation:N2}が[分散]{ぶんさん:fragmented:N3}し、[長期]{ちょうき:long-term:N3}[保守]{ほしゅ:maintenance:N1}が[困難]{こんなん:difficult:N3}になる」という[判断]{はんだん:judgment:N3}です。[新機能]{しんきのう:new feature:N3}は[新しい]{あたらしい:new:N4}エンドポイントの[追加]{ついか:addition:N3}や[既存]{きそん:existing:N1}エンドポイントへのフィールド[追加]{ついか:addition:N3}で[対応]{たいおう:handle:N1}します。\n\n#en\nkintone's API does not carry explicit major versions in the URL path; it has taken the policy of maintaining one stable contract over the long term. This is the judgment that \"increasing versions to v2, v3 fragments client implementations and makes long-term maintenance difficult.\" New features are handled by adding new endpoints or adding fields to existing endpoints.\n::\n\n::heading\n[廃止]{はいし:deprecation:N1}ライフサイクル\n\n#en\nDeprecation Lifecycle\n::\n\n::para\n[本当に]{ほんとうに:really:N3}[古い]{ふるい:old:N4}APIを[廃止]{はいし:deprecate:N1}する[必要]{ひつよう:need:N3}が[出た]{でた:emerged:N5}[場合]{ばあい:case:N3}でも、[一夜]{いちや:overnight:N4}にして[消す]{けす:to remove:N3}ことはありません。[最低]{さいてい:minimum:N2}でも[一]{いち:one:N5}[年]{ねん:year:N5}[以上]{いじょう:or more:N4}の[周知]{しゅうち:announcement:N2}[期間]{きかん:period:N3}を[設けて]{もうけて:set:N2}ドキュメントとリリースノートで[告知]{こくち:announce:N3}し、[管理]{かんり:admin:N2}[画面]{がめん:screen:N3}にも[警告]{けいこく:warning:N3}を[出して]{だして:show:N5}[移行]{いこう:migration:N2}を[促し]{うながし:to encourage:N1}ます。「[公開]{こうかい:public:N4}→[非]{ひ:non-:N3}[推奨]{すいしょう:recommended:N1}→[警告]{けいこく:warning:N3}→[廃止]{はいし:retirement:N1}」という[四]{よん:four:N5}[段階]{だんかい:stage:N2}のライフサイクルを[明示]{めいじ:clearly defined:N3}しているのが[特徴]{とくちょう:characteristic:N1}です。\n\n#en\nEven when truly old APIs need to be deprecated, they are not removed overnight. A notice period of at least one year is set, with announcements in documentation and release notes, and warnings shown in the admin screen to encourage migration. The clearly defined four-stage lifecycle — \"public → deprecated → warning → retired\" — is a key characteristic.\n::\n\n::heading\n[顧客]{こきゃく:customer:N1}[駆動]{くどう:driven:N1}の[拡張]{かくちょう:extension:N1}モデル\n\n#en\nCustomer-Driven Extension Model\n::\n\n::para\n[kintone]{きんとーん:kintone}は[標準]{ひょうじゅん:standard:N1}[機能]{きのう:feature:N3}だけで[全]{ぜん:all:N3}[業界]{ぎょうかい:industry:N4}・[全]{ぜん:all:N3}[業務]{ぎょうむ:business:N3}に[対応]{たいおう:handle:N1}するのではなく、「[プラグイン]{ぷらぐいん:plugin}」と「[カスタマイズ]{かすたまいず:customize}」という[二]{ふた:two:N5}つの[拡張]{かくちょう:extension:N1}[手段]{しゅだん:means:N3}を[顧客]{こきゃく:customer:N1}に[提供]{ていきょう:provide:N1}しています。[プラグイン]{ぷらぐいん:plugin}は[再]{さい:re-:N2}[利用]{りよう:use:N3}[可能]{かのう:possible:N3}なJavaScript\u002FCSSのパッケージ、[カスタマイズ]{かすたまいず:customize}は[個別]{こべつ:individual:N2}アプリに[書き込む]{かきこむ:to write:N3}コードです。[両者]{りょうしゃ:both:N3}はAPI[契約]{けいやく:contract:N1}に[強く]{つよく:strongly:N4}[依存]{いぞん:depend:N2}しているため、[後方]{こうほう:backward:N4}[互換性]{ごかんせい:compatibility:N2}を[壊す]{こわす:to break:N1}と[膨大]{ぼうだい:massive:N1}な[既存]{きそん:existing:N1}[資産]{しさん:asset:N3}が[一斉]{いっせい:all at once:N1}に[壊れ]{こわれ:to break:N1}ます。\n\n#en\nRather than handling every industry and every business operation with standard features alone, kintone provides customers with two extension means — \"plugins\" and \"customize.\" Plugins are reusable JavaScript\u002FCSS packages, and customize is code written into individual apps. Both depend strongly on the API contract, so breaking backward compatibility breaks a massive existing asset all at once.\n::\n\n::heading\nスキーマ[進化]{しんか:evolution:N3}の[実例]{じつれい:concrete example:N3}\n\n#en\nConcrete Examples of Schema Evolution\n::\n\n::para\n[例えば]{たとえば:for example:N3}、[文字列]{もじれつ:string:N3}フィールドが[内部的に]{ないぶてきに:internally:N3}「[文字列]{もじれつ:string:N3}（[1]{いち:one}[行]{ぎょう:line:N5}）」と「[文字列]{もじれつ:string:N3}（[複数]{ふくすう:multiple:N2}[行]{ぎょう:line:N5}）」に[分裂]{ぶんれつ:split:N1}した[場合]{ばあい:case:N3}でも、API[応答]{おうとう:response:N1}では[両者]{りょうしゃ:both:N3}を[区別]{くべつ:distinguish:N2}する[新]{しん:new:N4}フィールドを[追加]{ついか:add:N3}し、[既存]{きそん:existing:N1}フィールドの[意味]{いみ:meaning:N4}は[変更]{へんこう:change:N3}しません。[新規]{しんき:new:N3}クライアントは[新]{しん:new:N4}フィールドを[読み]{よみ:read:N5}、[古い]{ふるい:old:N4}クライアントは[従来]{じゅうらい:conventional:N1}フィールドだけで[動作]{どうさ:operate:N4}し[続け]{つづけ:continue:N3}ます。\n\n#en\nFor example, even when a string field is internally split into \"string (single line)\" and \"string (multiple lines),\" the API response adds a new field that distinguishes the two while leaving the meaning of the existing field unchanged. New clients read the new field; old clients continue to operate with only the conventional field.\n::\n\n::heading\n[互換性]{ごかんせい:compatibility:N2}テストの[自動化]{じどうか:automation:N3}\n\n#en\nAutomating Compatibility Tests\n::\n\n::para\n[後方]{こうほう:backward:N4}[互換性]{ごかんせい:compatibility:N2}を[人]{ひと:human:N5}の[注意]{ちゅうい:attention:N4}だけに[頼る]{たよる:to rely:N3}のは[危険]{きけん:risky:N3}です。[サイボウズ]{さいぼうず:Cybozu}は[過去]{かこ:past:N3}のレスポンスを[記録]{きろく:record:N2}しておき、[現]{げん:current:N3}バージョンが[同じ]{おなじ:same:N4}リクエストに[対して]{たいして:in response to:N3}[同じ]{おなじ:same:N4}[応答]{おうとう:response:N1}を[返す]{かえす:to return:N3}かを[継続的]{けいぞくてき:continuously:N1}に[検証]{けんしょう:verify:N1}する[契約]{けいやく:contract:N1}テストを[整備]{せいび:set up:N1}しています。フィールドの[追加]{ついか:addition:N3}は[許容]{きょよう:permitted:N3}されますが、[既存]{きそん:existing:N1}フィールドの[消失]{しょうしつ:disappearance:N3}や[型]{かた:type:N2}[変更]{へんこう:change:N3}は[テスト]{てすと:test}[失敗]{しっぱい:failure:N3}として[即座]{そくざ:immediately:N1}に[検知]{けんち:detected:N1}されます。\n\n#en\nRelying solely on human attention for backward compatibility is risky. Cybozu has set up contract tests that record past responses and continuously verify whether the current version returns the same response to the same request. Field additions are permitted, but disappearances or type changes of existing fields are immediately detected as test failures.\n::\n\n::heading\nレート[制限]{せいげん:limit:N3}と[公平性]{こうへいせい:fairness:N3}\n\n#en\nRate Limits and Fairness\n::\n\n::para\n[公開]{こうかい:public:N4}APIには[必ず]{かならず:always:N3}レート[制限]{せいげん:limit:N3}を[設けて]{もうけて:set:N2}、[特定]{とくてい:specific:N3}クライアントが[全体]{ぜんたい:overall:N3}[性能]{せいのう:performance:N3}を[圧迫]{あっぱく:to pressure:N1}しないようにします。[kintone]{きんとーん:kintone}では[一]{いち:one:N5}テナント[当たり]{あたり:per:N3}の[毎]{まい:every:N5}[秒]{びょう:second:N2}リクエスト[数]{すう:count:N3}に[上限]{じょうげん:upper limit:N3}を[設け]{もうけ:to set:N2}、[超えた]{こえた:exceeded:N2}[場合]{ばあい:case:N3}は[429]{よんにきゅう:429} (Too Many Requests)を[返し]{かえし:to return:N3}ます。レート[制限]{せいげん:limit:N3}の[値]{あたい:value:N3}も[公開]{こうかい:public:N4}APIの[一部]{いちぶ:part:N3}とみなされ、[縮小]{しゅくしょう:tighten:N1}する[際]{さい:occasion:N3}は[周知]{しゅうち:announcement:N2}[期間]{きかん:period:N3}が[必要]{ひつよう:necessary:N3}です。\n\n#en\nPublic APIs always have rate limits set so that no specific client pressures overall performance. kintone sets an upper limit on per-tenant requests per second and returns 429 (Too Many Requests) when exceeded. Rate limit values themselves are considered part of the public API, and tightening them requires a notice period.\n::\n\n::heading\nおわりに\n\n#en\nConclusion\n::\n\n::para\n[十数年]{じゅうすうねん:over a decade:N3}にわたってAPIを[壊さ]{こわさ:break:N1}ずに[進化]{しんか:evolve:N3}させてきた[実績]{じっせき:track record:N2}は、[新規]{しんき:new:N3}[機能]{きのう:feature:N3}を[速く]{はやく:fast:N3}[出す]{だす:to ship:N5}よりも[既存]{きそん:existing:N1}[顧客]{こきゃく:customer:N1}の[業務]{ぎょうむ:business:N3}を[守る]{まもる:to protect:N3}ことを[優先]{ゆうせん:prioritize:N3}するという[文化]{ぶんか:culture:N3}そのものです。「[追加]{ついか:add:N3}してよい、[変更]{へんこう:change:N3}するな、[削除]{さくじょ:remove:N1}は[長い]{ながい:long:N5}[周知]{しゅうち:announcement:N2}を[挟め]{はさめ:insert:N2}」という[原則]{げんそく:principle:N2}は[古典的]{こてんてき:classical:N1}ですが、[長期]{ちょうき:long-term:N3}[運用]{うんよう:operation:N4}するプラットフォームには[今]{いま:now:N5}も[有効]{ゆうこう:valid:N2}な[指針]{ししん:guideline:N2}です。\n\n#en\nThe track record of evolving the API for over a decade without breaking it is itself a culture that prioritizes protecting existing customers' operations over shipping new features quickly. The principles \"additions are welcome, do not change, deletion requires a long notice period\" are classical, but they remain valid guidelines for platforms operated over the long term.\n::\n"]