typespec1-6 Exercise 1: A Reply Template ============================================== envelope.tsp (TypeSpec 1.17.0; OpenAPI 3.1.0): import "@typespec/http"; using Http; @service(#{ title: "Envelopes" }) namespace Envelopes; model Book { id: string; title: string; } model Author { id: string; name: string; } /** A response wrapper carrying the request id. */ model Reply { data: T; requestId: string; } @route("/books/{id}") interface Books { @get read(@path id: string): Reply; } @route("/authors/{id}") interface Authors { @get read(@path id: string): Reply; } The operations table: operation inputs responses GET /authors/{id} path:id 200 GET /books/{id} path:id 200 The response of GET /authors/{id}, as generated: responses: '200': description: The request has succeeded. content: application/json: schema: type: object required: - data - requestId properties: data: $ref: '#/components/schemas/Author' requestId: type: string description: A response wrapper carrying the request id. The components section of that file has only Author and Book. There is no schema for the Reply: Reply and Reply were each written out inside their operation. Adding @friendlyName("{name}Reply", T) above the model (envelope2.tsp) changed the components to Author, AuthorReply, Book and BookReply, and the operations to $ref them: AuthorReply: type: object required: - data - requestId properties: data: $ref: '#/components/schemas/Author' requestId: type: string description: A response wrapper carrying the request id. WHAT HAPPENED Without a name the template instances were anonymous and inline. With @friendlyName each instance became a named schema, named by the argument. The operations table is identical in both versions: the difference is only visible in the schemas, which is why a table of operations would never have shown it. WHY THIS WORKS AS AN ANSWER --------------------------- It reproduces the chapter's main surprise on a new template. Reading the components section after using a template is the habit to keep.