microsoft / microsoft/typespec

[Feature Request] HTTP: declare custom/extended HTTP methods and emit OpenAPI 3.2 additionalOperations

Open
#11,668 2 comments 1 reaction 0 assignees View on GitHub
design:needed emitter:openapi3 lib:http triaged:core
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.