microsoft / microsoft/typespec
[Feature Request] HTTP: declare custom/extended HTTP methods and emit OpenAPI 3.2 additionalOperations
- Dominant language
- Java
- Stars
- 5.9k
- Forks
- 394
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 104
Description
### Clear and concise description of the problem
OpenAPI 3.2 added the `additionalOperations` field on the Path Item Object, so a document can now describe operations using HTTP methods outside the classic eight (WebDAV's PROPFIND/PROPPATCH/MKCOL/MOVE/COPY/LOCK, LINK/UNLINK, vendor methods, etc.), alongside the new first-class `query` method (#11171 tracks QUERY specifically).
TypeSpec currently cannot express such operations at all:
- `@typespec/http`'s `HttpVerb` is the closed union `"get" | "put" | "post" | "patch" | "delete" | "head"`, and there is no decorator to declare any other method.
- `@typespec/openapi3` (1.15.0) already ships the 3.2 output types — `OpenAPIPathItem3_2` includes `additionalOperations?: Record` — but no code path ever writes it, since the language cannot produce such an operation.
So an API that serves, say, a WebDAV surface next to its REST surface can bring the REST half under TypeSpec but must leave the WebDAV half entirely outside the contract, even when targeting `openapi-versions: [3.2.0]` where the document format can now say it.
### Describe the solution you'd like
A way to declare an operation with an arbitrary (registered or vendor) HTTP method, for example:
```tsp
@method("PROPFIND")
@route("/dav/{path}")
op propfind(@path path: string, @header depth?: string): MultiStatusResponse;
```
with:
- the method carried on `HttpOperation` so third-party emitters can read it (we maintain server emitters built on `@typespec/http` and would route these to the framework's custom-method registration),
- `@typespec/openapi3` emitting it under `additionalOperations` when the target version is `3.2.0`, and a clear diagnostic (rather than silent omission) when targeting 3.0/3.1 where the field does not exist,
- `query` presumably staying first-class per #11171, with this mechanism covering the long tail.
The exact surface (a `@method` decorator vs widening `@route`/op declarations) is your call — the ask is that the fact be declarable and emitted.
### Describe alternatives you've considered
- Keeping the non-standard-method surface hand-written outside the spec (what we do today) — works, but splits one service's contract across two sources of truth.
- Post-processing the emitted document to inject `additionalOperations` — rejected; it re-creates exactly the document/server divergence spec-first exists to remove.
Happy to contribute the implementation if the design direction is agreed.
Contributor guide
Research direction
Start in @typespec/http's HttpVerb and HttpOperation model, then trace @typespec/openapi3's OpenAPIPathItem3_2 and path-item emission. Confirm how target versions are selected and how diagnostics are reported. Done means custom methods are declarable, exposed to emitters, emitted as additionalOperations for OpenAPI 3.2, and diagnosed for unsupported targets.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- openapi
- Domain
- api, backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100