microsoft / microsoft/typespec

Override service server decorator with nested sever decorator

Open
#6,773 0 comments 0 reactions 0 assignees View on GitHub
compiler:core design:needed triaged:core
Dominant language
Java
Stars
5.9k
Forks
394
Avg merge
1d 23h
Merged PRs (30d)
104

Description

It seems i cannot specify a specific server url for a specific endpoint, when the default server URL is already assigned to the top level namespace/service.

Consider the following. We have a service which looks like:

```typespec
import "@typespec/http";
import "../types";
import "./addresses";
import "./subscribers";
import "./subscriber-guest-token";
import "./subscriber-invite-token";
import "./external-laml-handler";
import "./external-laml-handler-addresses";
import "./external-swml-handler";
import "./external-swml-handler-addresses";
import "./ai-agent";
import "./ai-agent-addresses";
import "./cxml-application";
import "./cxml-application-addresses";
import "./embeds-tokens";

using TypeSpec.Http;
using Types.StatusCodes;

@service({
title: "Call Fabric API",
})
@server("https://{space_name}.example.com/api/fabric/", "Endpoint", {
space_name: string = "{Your_Space_Name}";
})
@useAuth(BasicAuth)
@doc("API to access/manage Call Fabric objects.")
namespace FabricAPI;
```

You can see we are importing all the declared endpoints for this service. The endpoint we are focusing on is the `embeds-tokens`, which looks like:

```typespec
// Define the API path for embeds
@useAuth({ type: Http.AuthType.noAuth })
@server("https://embeds.example.com/api/fabric/", "Endpoint")
@route("/embeds/tokens")
namespace FabricAPI.EmbedsTokens {
@tag("Embeds Tokens")
@friendlyName("Embeds Tokens")
interface EmbedsTokens {
@summary("Create Embeds Tokens")
@doc("Exchanges a public Click-to-Call (C2C) token for a short-lived, private embed guest token used to authorize a call. This allows secure activation of the C2C widget without exposing sensitive credentials.")
@post
create(@body body: EmbedsTokensRequest):
{ @statusCode statusCode: 201; @body subscriber: EmbedsTokensResponse; } |
StatusCode401 |
StatusCode404 |
StatusCode403;
}
}
```

Notice how in this endpoint we set the server so it has no variables and the `space_name` variable from the top level service has replaced with a static `embeds` in the url. This is intentional as the api is not bounded to a persons account in this case, but still is part of the service pathway which is `/api/farbic/endpoint`.

In a openapi spec, I can solve this by declaring another `servers` property directly inside the endpoint schema.

Which would look like:

```yaml
/embeds/tokens:
servers:
- url: https://embeds.example.com/api/fabric
description: A description of the server.
post:
operationId: EmbedsTokens_create
summary: Create Embeds Tokens
description: Exchanges a public Click-to-Call (C2C) token for a short-lived, private embed guest token used to authorize a call. This allows secure activation of the C2C widget without exposing sensitive credentials.
parameters: []
responses:
'201':
description: The request has succeeded and a new resource has been created as a result.
content:
application/json:
schema:
$ref: '#/components/schemas/EmbedsTokensResponse'
'401':
description: Access is unauthorized.
content:
application/json:
schema:
anyOf:
- type: string
enum:
- Unauthorized
- type: string
enum:
- Forbidden
'404':
description: The server cannot find the requested resource.
content:
application/json:
schema:
type: string
enum:
- Not Found
tags:
- Embeds Tokens
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/EmbedsTokensRequest'
security:
- {}
```

However, even with the `server` decorator on the endpoint (which shows as valid) the spec will generate like such:

```yaml
/embeds/tokens:
post:
operationId: EmbedsTokens_create
summary: Create Embeds Tokens
description: Exchanges a public Click-to-Call (C2C) token for a short-lived, private embed guest token used to authorize a call. This allows secure activation of the C2C widget without exposing sensitive credentials.
parameters: []
responses:
'201':
description: The request has succeeded and a new resource has been created as a result.
content:
application/json:
schema:
$ref: '#/components/schemas/EmbedsTokensResponse'
'401':
description: Access is unauthorized.
content:
application/json:
schema:
anyOf:
- type: string
enum:
- Unauthorized
- type: string
enum:
- Forbidden
'404':
description: The server cannot find the requested resource.
content:
application/json:
schema:
type: string
enum:
- Not Found
tags:
- Embeds Tokens
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/EmbedsTokensRequest'
security:
- {}
```

It seems reasonable to follow Open APIs behavior here.

[Example Playground](https://typespec.io/playground/?c=aW1wb3J0ICJAdHlwZXNwZWMvaHR0cCI7DQrGAnVzaW5nIFR5cGVTcGVjLkh0dHDHHEBzZXJ2aWNlKCN7DQogIHRpdGxlOiAiQ2FsbCBGYWJyaWMgQVBJIiwNCn0pxy5lcigixF9zOi8ve3NwYWNlX25hbWV9LmV4YW1wbGUuY29tL2FwaS9mxUAvIiwgIkVuZHBvaW50IiwgxWjKNzogc3Ry5ACePSAie1lvdXJfU8UcTsRT5ADCxXh1c2VBdXRoKEJhc2ljxArEFWRvYygiQVBJIHRvIGFjY2Vzcy9tYW5hZ2UgIOwAwG9iamVjdHMuIikNCsRyxXzHHUFQSekBJW1vZGVsIEVtYmVkc1Rva2Vuc1JlcXVlc3TmALMgIMZxQ2xpY2vEc8VkxSnEWsUh5wECKCJjMmNfN2FjYzBlNWU5Njg3MDZhMDMyOTgzY2Q4MGNkY2EyMTnINnTEQ%2BgBB%2BQA8fgAjXNwb25zZeYAjuYAjEVuY3J5cHRlZCBn5QCpxUvlAOnsAI1leUpoYkdjaU9pSmthWElpTENKbGJtTcQQQk1qVTJSME5OSWl3aVkyZ8QUd2RXTXViSFpvTG0xbMQYZEhsd0lqb2lVMEZVSW4wLsdh9QC4DQovLyBEZWZpbmUgdGhl5AI9IHBhdGggZm9yIGXlAM%2FrAc97IOQCsTog5AKRLsQS5AKjLm5vxAsg9QJxxkP%2FAmvmAmvEP3JvdXRlKCLHNy%2FlALNz9wIJLuwBbukB9HRhZygixhrmAe3FP8UbZnJpZW5kbHnkAqvXJGludGVyZsRn1F3FRnN1bW1hcnkoIkNyZWF0yCnPSOoCf0V4Y2hhbmdlcyBhIHB1YmxpYyDlApItdG8t5QKSKEMyQynmAZ3lAXVhIHNob3J0LWxpdmVkLCBwcml2xGflARLsAjcgdXNlZOUDS3V0aG9yaXplIGEgY2FsbC4gVGhpcyBhbGxvd3Mgc2VjdXJlIGFjdMRIaW9uIG9m5QHqQzJDIHdpZGdldCB3aXRob3V0IGV4cG%2FlBHpzZW5zaXRpdmUgY3JlZGVudGlhbOYDkekA3XBvc3TKD2PlAQwoQGJvZHkgxAU69AOZKTrKMnsgQHN0YXR1c0NvZGUgygs6IDIwMTsgxkpzdWJzY3JpYmVy0FDmA1w7IH3GUn0NCn0%3D&e=%40typespec%2Fopenapi3&options=%7B%7D)

_Originally posted by @Devon-White in https://github.com/microsoft/typespec/discussions/6696_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.