Skip to content

Allow @route decorator to act as a prefix instead of override when ising the operation definition #9531

@artsiommiksiuk

Description

@artsiommiksiuk

Clear and concise description of the problem

https://typespec.io/playground/?e=%40typespec%2Fopenapi3&c=aW1wb3J0ICJAdHlwZXNwZWMvaHR0cCI7CtIZb3BlbmFwaSI7Cgp1c2luZyBIdHRwO8cMT3BlbkFQSTsKCgpAcG9zdApAcm91dGUoIi9iYXRjaC9nZXQiKQpvcCDFD0dldDxUPigpOiBUxTLILGNyYWJzzihDxBMgaXPKOXsga2luZDogIsQuIiB9PtVDaW50ZXJmYWNlIMZCewog31TPVH0%3D&options=%7B%7D&vs=%7B%7D

import "@typespec/http";
import "@typespec/openapi";

using Http;
using OpenAPI;


@post
@route("/batch/get")
op batchGet<T>(): T;


@route("/crabs")
op batchGetCrabs is batchGet<{ kind: "crab" }>;


@route("/crabs")
interface Crabs {
  batchGetCrabs is batchGet<{ kind: "crab" }>;
}

I want to have an operation defining postfix for any operation which implements it.
E.g. root level batchGetCrabs, in my ideal version should result into route /crabs/batch/get, but rn operation definition level @route overrides template @route decorator, and OAS generated document having just /crabs as a route.

I can partially achieve this with the second version, which is wrapping whole thing into Crabs interface or namespace. This creates correct route path, but now suffers from having additional prefix in the operation id. Setting manually @operationId nullifying prefixes can be a bit too much just because I have more than a hundred routes then to go through and have to maintain manually. Not impossible, but doesn't make sense.

To sum it, result I want to have is operation under /crabs/batch/get and operationId batchGetCrabs.

Therefore I see several potential solutions:

  1. Extend @route decorator with optional flag indicating it is a route prefix or not, so on rendering the routes decorators infos can be concatenated instead of replace.
  2. Introduce another decorator@prefix. In this case this decorator can serve many purposes, as general use prefixing decorator which can be used in any place of a hierarchy to indicate that when assembling this part should not override, but be present on a certain level. E.g. in my case I can use it for both cases: for root I'll be using something like @prefix("/crabs", route), which says use /crabs as a prefix for any underlying route decorator; for interface case @prefix(null, operationId) - use nothing as an operationId override for this interface.
  3. Allow @operationId to be set on interfaces and namespace and accept null, in order to completely disable this part of hierarchy from affecting final operationId string.

Checklist

  • Follow our Code of Conduct
  • Read the docs.
  • Check that there isn't already an issue that request the same feature to avoid creating a duplicate.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions