Preserving API Quality in AI-Assisted Development

💡 Quick Summary (TL;DR):
- Before coding: Ask the agent to explain the business process, resource model, access boundaries, error behaviour, and contract change. Do not let it fill missing information with assumptions.
- During review: Independently check HTTP methods, retry behaviour, record ownership, the error contract, overly broad data access, and backward compatibility.
- Before delivery: Enforce OpenAPI validation, contract and breaking-change tests, negative authorization tests, and documentation alignment in the pipeline. People still own the business decisions.
In 2021, I published a seven-part REST series on this site. It covered RESTful API components, design details, URI structure, error handling, authentication, security, and documentation. Six of those articles also had English editions.
Most of the principles in those articles still hold. I am not retiring the series because they became wrong. It was built for a way of working in which developers would study each subject in sequence, learn the REST decisions involved, and then write the code.
Today, many developers describe what they need to an AI coding agent in a few sentences and work from the resulting code. Keeping the old articles separate would leave sound guidance inside a learning path that is now less common. I decided to retire them and replace them with this article.
I will not repeat the entire series here. Instead, I will move its principles into three places where they matter in AI-assisted API work: the initial prompt, code review, and delivery checks.
Why is a REST API prompt incomplete?
Ask an agent to “write a CRUD API for customer records” and you may have working endpoints in minutes. But working code does not answer these questions:
- Can a customer record be physically deleted, archived, or anonymized?
- What happens when the same deletion request arrives twice?
- Under what conditions may one user see another customer’s record?
- Who is affected if a response used by the mobile app changes?
- Can a client safely retry after receiving an error?
The first step in REST quality is making those decisions. URIs and application code come later. An agent will often fill an omitted decision with a reasonable-looking assumption. A technical preference can then quietly become a business decision about data retention, access, or integration.
An instruction to give the agent before it writes code
The following is a short opening instruction for a new API or endpoint task:
Do not write code yet. First, for this API change:
1. Explain the business process, the resource owner, and the expected outcome.
2. List the resources, their relationships, and the URI structure you propose.
3. For every endpoint, state the HTTP method, its side effects, and what happens
if the same request is repeated.
4. Define successful responses, error conditions, and what the client should do
for each error.
5. Show authentication, authorization, role, tenant, and record-ownership checks
separately.
6. List input validation, returned fields, request size, rate limits, logging,
and sensitive-data risks.
7. Show the proposed difference from the current OpenAPI contract and any
backward-compatibility risk.
8. If you propose a new database, cache, queue, or service, explain the concrete
need it addresses and its operating cost.
If information is missing, do not make assumptions. List the questions and wait.
This instruction does not teach REST to the agent. It states which decisions must be visible before code is written. It also prevents a deletion or retention decision that belongs to the product owner from being implemented as a technical assumption.
How to preserve earlier REST principles with AI
Condensing the detail of the old series into seven checks produces this table:
| Principle | Tell the agent | Check during review |
|---|---|---|
| Components and architecture | Do not add a database, cache, queue, service, or framework until the need is demonstrated. State the problem each component solves and its operating cost. | Does every dependency answer a real load, reliability, or integration need? Can the team operate it? |
| Resources and URI design | Derive URIs from durable resources in the business domain. Apply the existing API’s rules for naming, plurals, lowercase, and sub-resources consistently. | Do the URI and HTTP method make the operation clear together? Is the same resource named differently elsewhere? |
| HTTP methods | State safe, idempotent, and retryable behaviour for every endpoint. Do not hide work with side effects behind GET. | Can a repeated request create the same outcome twice? Does GET change state? Do PUT, PATCH, and DELETE match the contract? RFC 9110 defines these semantics. |
| Error handling | Use one machine-readable error format across endpoints. Define the status code, safe message, field errors, problem code, and request ID. | Are 401, 403, 404, 422, 429, and 5xx responses distinct? Do they leak stack traces or sensitive information? Can the client tell what to do next? RFC 9457 specifies a common problem-response format. |
| Identity and authorization | Design authentication, functional authorization, and record-ownership checks separately. State role, scope, tenant, and object-ownership rules per endpoint. | Can a user with a valid token access another user’s or tenant’s record by changing an ID? Is an administrative endpoint open to an ordinary user? |
| Security and abuse | Validate every input with a schema. Limit writable and returned fields explicitly. Address request size, rate limits, secret handling, logging, and abuse scenarios. | Can protected data be changed by sending extra fields? Is more data returned than necessary? Are there negative authorization, resource-consumption, and sensitive-workflow tests? The OWASP API Security Top 10 is a useful starting point for review. |
| Contract and documentation | Prepare the OpenAPI diff before the application code. Define request, response, error, security, and rate-limit behaviour with examples. | Does the code match the contract? Does the change break existing clients? Are the documentation and published contract in the same version? OpenAPI defines the format of this shared contract. |
One narrow HATEOAS principle is still worth preserving here: when the next valid action is part of the business workflow, the response should not force the client to guess it. In AI-assisted API work, links or action affordances need to be an explicit contract decision, not something an agent improvises inside JSON.
This table can serve as an API-development rule. Put rules that apply to all API work in the repository’s persistent agent instructions. Keep product- or endpoint-specific decisions in the work brief and the OpenAPI contract.
An instruction for a second agent to review the change
Telling the agent that wrote the code to review itself can help. But an agent working in the same context may not recognize its own assumption as an error. Review is a stronger control when it is a separate task and, where possible, runs in a separate agent context.
Review this API change as an independent reviewer. Do not change code yet.
Do not treat the implementing agent’s explanation as evidence; use the existing
OpenAPI contract, repository rules, and tests instead.
Check the following:
- Are the resource model and URIs consistent with the existing API?
- Are HTTP methods, side effects, and retry behaviour correct?
- Do success and error responses match the contract?
- Are authentication, functional authorization, tenant, and record-ownership
checks implemented separately?
- Are inputs, writable fields, and returned data broader than necessary?
- Is there a contract change that could break existing clients?
- Alongside the successful flow, are there tests for negative authorization,
validation, rate limits, and retries?
For every finding, state the affected endpoint, evidence, risk, and required test.
Do not make corrections until the review is approved.
The purpose of this review is not to fix code style. It is to find where the agent has misunderstood a business decision, broken REST behaviour, or skipped a security boundary.
Which errors should the pipeline stop automatically?
Prompt and review alone are not enough. If repeatable rules do not enter the pipeline, the same error can reappear in another change. At a minimum, automate these four checks:
- Is the OpenAPI contract valid and aligned with the application?
- Does the contract diff introduce a backward-incompatible change?
- Do contract tests and negative authorization, validation, and retry tests pass?
- Is the published documentation in the same version as the contract?
Changes that affect the access model, payment behaviour, sensitive data, data-deletion policy, or existing clients should also stop for approval by a named person. Another agent saying “looks good” does not take ownership of those decisions.
Why turn the old series into one article?
The old series aimed to help developers learn REST. The current need is to keep that knowledge from disappearing within an AI-assisted development flow.
That makes one control sequence more useful than seven separate articles:
- Make the business decision.
- Have the agent surface the missing decisions.
- See the contract before the code.
- Send the implementation through independent review.
- Make repeatable rules mandatory in the pipeline.
If a team cannot make these controls visible in prompts, repository instructions, and the pipeline, it has not carried its earlier REST knowledge into its new way of working. An agent can write code quickly. People still decide what the API promises and which risks it cannot accept.
