Skip to content

Override service server decorator with nested sever decorator #6773

Open
@Devon-White

Description

@Devon-White

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:

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:

// 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:

  /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:

  /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

Originally posted by @Devon-White in #6696

Metadata

Metadata

Assignees

No one assigned

    Labels

    compiler:coreIssues for @typespec/compilerdesign:neededA design request has been raised that needs a proposaltriaged:core

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions