Global Trend Radar
Dev.to US tech 2026-05-08 18:00

APIデザインのためのClaudeコード:6ヶ月後に後悔しないエンドポイントの出荷をやめた方法

原題: Claude Code for API Design: How I Stopped Shipping Endpoints I Regret Six Months Later

元記事を開く →

分析結果

カテゴリ
IT
重要度
62
トレンドスコア
24
要約
この記事では、APIデザインにおけるClaudeコードの活用法について述べています。著者は、過去に後悔したエンドポイントの出荷を避けるための戦略を共有し、設計段階での慎重な考慮が重要であることを強調しています。具体的な手法や実践的なアドバイスを通じて、開発者がより良いAPIを構築するための洞察を提供しています。
キーワード
Originally published on Hashnode . Cross-posted for the DEV.to community. The first public API I designed had 47 endpoints. Eight months later, 31 of them were either deprecated, broken, or quietly ignored by the only client that ever consumed them. Two were so badly named that we shipped a v2 just to rename them. One returned a different shape depending on which day of the week you called it, because of a bug nobody had caught in code review. The whole thing was a monument to what happens when an engineer designs an API by writing endpoints in the order they get requested. That was 2021. Since then I have shipped four more public APIs and a handful of internal ones. Three of them I actually like. The other one is fine. None of them have the embarrassing mid-stream redesigns that the first one had. The difference is not that I got smarter. The difference is that I stopped designing APIs by typing route handlers and started designing them by having a conversation with Claude Code about what the API is for. This is a workflow article, not a theory article. I am going to walk you through how I use Claude Code to design APIs from a blank slate, how I review existing APIs for design problems before they ship, and how I evolve APIs without breaking the clients that depend on them. The patterns are language and framework agnostic. I have used them for REST, GraphQL, and gRPC services. The tooling matters less than the discipline. Why API Design Goes Wrong Most APIs that age badly share a common failure mode. The team designs the API by following the immediate request pattern. The first client wants a way to fetch users, so we add GET /users . The second client wants a way to fetch a user by id, so we add GET /users/:id . The third client wants to filter users by status, so we add GET /users?status=active . Six months later we have 40 endpoints, three different ways to filter, two different pagination strategies, and an inconsistent response envelope. The problem is not that any individual decision was wrong. Each endpoint, viewed in isolation, made sense at the time it was added. The problem is that nobody designed the API as a whole. The API emerged from accumulated requests, and emergent designs almost always have rough edges. The second failure mode is designing for the present implementation instead of the future contract. The team exposes the database schema directly because that is what the implementation looks like today. Six months later the database schema changes and now the API has to either change too (breaking clients) or include a translation layer that nobody has time to maintain. Either way, somebody is unhappy. The third failure mode is the optimistic naming problem. The team names the endpoint after what it does today, not what it represents conceptually. POST /sendWelcomeEmail becomes a problem the moment the product team decides welcome emails should sometimes be SMS messages. Now you have an endpoint named after a transport when the actual concern is the welcome flow. APIs are contracts. Contracts are about what they promise, not how they are currently fulfilled. I have made all three of these mistakes more than once. The reason I have stopped making them is that Claude Code now flags them before they ship. The Design Conversation Skill Before I write any route handlers, I have a design conversation with Claude Code about what the API is for. This is not a casual chat. It is a structured process that produces a markdown document I commit to the repo before the first endpoint exists. The conversation has five sections. The first section is the actor inventory . Who calls this API, and what are they trying to accomplish? Not what features they need, but what jobs they are trying to do. A mobile app trying to render a user profile is doing a different job than a backend service trying to validate a webhook signature, even if both involve the same user record. Most APIs are easier to design when you know the jobs first. The second section is the resource inventory . What are the nouns this API talks about? Not the database tables. The conceptual nouns. Sometimes a database has six tables but the API only has two resources because the other four are implementation details. Sometimes the database has one table but the API has three resources because what looks like one entity to the storage layer is three different concepts to the consumer. The third section is the operation inventory . For each resource, what operations does the API support? Create, read, update, delete are the obvious ones, but most APIs need more. Listing with filters. Bulk operations. State transitions that are not just updates. Search. Subscriptions. Each one needs to be explicit so that nothing surprises us later. The fourth section is the consistency rules . How does this API handle pagination? Errors? Idempotency? Versioning? Authentication? These are the cross-cutting concerns that, if left ad-hoc, end up inconsistent across endpoints. Decide them once and document them. The fifth section is the explicit non-goals . What is this API not for? Which use cases are out of scope? This section saves more arguments than any other section in the document. Six months from now when somebody asks "can we add a search endpoint to this API," the non-goals section gives a principled answer. The skill takes my rough description of what I am building and produces a draft of all five sections. I review it, push back on the parts that feel wrong, and iterate until I have a document I would be willing to defend in a design review. The Endpoint Specification Skill Once the design document is settled, I move to specifying individual endpoints. The endpoint specification skill takes a resource and an operation and produces a complete specification including the URL path, the HTTP method, the request shape, the response shape, the error responses, the idempotency behavior, and the authentication requirements. This is where most of the bugs in API design get caught. Writing a specification forces you to confront edge cases that are easy to ignore when you are typing route handlers. What happens if the request body is malformed? What happens if the resource does not exist? What happens if the user is authenticated but lacks permission? What happens if a required field is empty versus missing? The specification format I use looks like this: POST /api/v1/orders Auth: Bearer token (scope: orders:write) Idempotency: Idempotency-Key header (UUID, 24h retention) Request: { customer_id: string (required) line_items: [{ product_id: string (required) quantity: integer (required, min: 1, max: 999) unit_price_cents: integer (optional, defaults to product price) }] (required, min: 1, max: 50) shipping_address: AddressObject (required) notes: string (optional, max: 500) } Response 201: Order resource (full shape) Location: /api/v1/orders/{id} Response 400: ValidationError with field-level details Response 409: IdempotencyConflict if same key seen with different body Response 422: BusinessLogicError (e.g., product out of stock) The skill produces these specifications for every endpoint in the API. I commit them to a specs/ directory. They become the contract that the implementation has to match and that the tests verify. The discipline of writing specifications first sounds bureaucratic. It is not. It is faster than typing route handlers and discovering the design problems through bugs. The specifications take maybe an hour each. The bugs they prevent take days each. Want the playbook for setting up Claude Code skills like the API design conversation skill? It is in the Claude Code skills guide . Start with one skill and add more as you find friction in your workflow. The Consistency Audit Skill Designing endpoints in isolation is how inconsistencies creep in. The third endpoint uses created_at and the fourth uses createdAt and the fifth uses creationDate . The first list endpoint uses cursor pagination and the second uses offset pagination. The first error response includes a code field and the second does not. Each individual decision is fine. The collection is a mess. The consistency audit skill takes the full set of endpoint specifications and produces a report of inconsistencies. Naming conventions, pagination strategies, error formats, authentication patterns, response envelopes. Anything that varies across endpoints when it should not. I run this skill at three points in the API lifecycle. First, after the initial design pass, before any code is written. The earliest fixes are the cheapest. Second, after every batch of new endpoints is added. The skill catches drift from the original conventions. Third, before any major release. The skill provides a final sanity check. The audit report is brutal in a useful way. Last month it told me I had three different pagination strategies in an API I thought was internally consistent. I had been pattern matching against whichever endpoint I was looking at most recently. The skill noticed what my tired eyes had missed. The Versioning Strategy Skill Versioning is where most APIs go to die. The team picks a strategy that sounds reasonable, ships v1, and discovers six months later that the strategy does not work for the actual changes the API needs. By then there are clients depending on v1 and changing the strategy means breaking them. The versioning strategy skill takes the API design document and produces a versioning plan that covers four scenarios. How do additive changes get versioned? How do breaking changes get versioned? How long does each version stay supported? What is the deprecation process? The reason this matters is that different versioning strategies suit different APIs. URL path versioning ( /api/v1/ , /api/v2/ ) is simple but creates massive code duplication if you maintain multiple major versions. Header versioning is more flexible but harder for clients to discover. Date-based versioning works well for