You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: openapi/frameworks/typespec.mdx
+44-33Lines changed: 44 additions & 33 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,7 +29,7 @@ model Address {
29
29
@route("/stores")
30
30
interface Stores {
31
31
list(@query filter: string): Store[];
32
-
read(@path id: Store): Store;
32
+
read(@path id: string): Store;
33
33
}
34
34
```
35
35
@@ -130,7 +130,7 @@ Just like in TypeScript, code can be organized into files, folders, and modules,
130
130
131
131
Here's an example of how to import files, folders, and modules in TypeSpec:
132
132
133
-
```typescript filename="main.tsp"
133
+
```typespec filename="main.tsp"
134
134
import "./books.tsp"; // Import a file
135
135
import "./books"; // Import main.tsp in a folder
136
136
import "/books"; // Import a TypeSpec module's main.tsp file
@@ -142,7 +142,7 @@ Modules can be installed using npm, and the `import` statement imports them into
142
142
143
143
Namespaces are defined using the `namespace` keyword, followed by the namespace name and a block of type definitions. Here's an example:
144
144
145
-
```typescript
145
+
```typespec
146
146
namespace MyNamespace {
147
147
model User {
148
148
id: string;
@@ -153,7 +153,7 @@ namespace MyNamespace {
153
153
154
154
They may also be defined at the file level, using the `namespace` keyword followed by the namespace name and a block of type definitions. Here's an example:
155
155
156
-
```typescript
156
+
```typespec
157
157
namespace MyNamespace;
158
158
159
159
model User {
@@ -172,7 +172,7 @@ model Post {
172
172
173
173
[Models](https://typespec.io/docs/language-basics/models) in TypeSpec are similar to OpenAPI's `schema` objects. They define the structure of the data that will be sent and received by an API. Models are defined using the `model` keyword, followed by the model name and a block of properties. Here's an example:
174
174
175
-
```typescript filename="main.tsp"
175
+
```typespec filename="main.tsp"
176
176
model User {
177
177
id: string;
178
178
name: string;
@@ -182,7 +182,7 @@ model User {
182
182
183
183
Models are composable and extensible. Models can reference other models within a definition, extend a model with additional properties, and compose multiple models into a single model. Here's an example of model composition:
184
184
185
-
```typescript filename="main.tsp"
185
+
```typespec filename="main.tsp"
186
186
namespace WithComposition {
187
187
model User {
188
188
id: string;
@@ -245,22 +245,22 @@ components:
245
245
246
246
[Operations](https://typespec.io/docs/language-basics/operations) in TypeSpec are similar to OpenAPI operations. They describe the methods that users can call in an API. Operations are defined using the `op` keyword, followed by the operation name. Here's an example:
247
247
248
-
```typescript filename="main.tsp"
249
-
op listUsers(): User[]; // Defaults to GET
250
-
op getUser(id: string): User; // Defaults to GET
251
-
op createUser(@body user: User): User; // Defaults to POST with a body parameter
248
+
```typespec filename="main.tsp"
249
+
op list(): User[]; // Defaults to GET
250
+
op read(id: string): User; // Defaults to GET
251
+
op create(@body user: User): User; // Defaults to POST with a body parameter
252
252
```
253
253
254
254
### Interfaces in TypeSpec
255
255
256
256
[Interfaces](https://typespec.io/docs/language-basics/interfaces) in TypeSpec group related operations together, similar to OpenAPI's `paths` object. Interfaces are defined using the `interface` keyword, followed by the interface name and a block of operations. Here's an example:
257
257
258
-
```typescript filename="main.tsp"
258
+
```typespec filename="main.tsp"
259
259
@route("/users")
260
260
interface Users {
261
-
op listUsers(): User[]; // Defaults to GET /users
262
-
op getUser(id: string): User; // Defaults to GET /users/{id}
263
-
op createUser(@body user: User): User; // Defaults to POST /users
261
+
op list(): User[]; // Defaults to GET /users
262
+
op read(id: string): User; // Defaults to GET /users/{id}
263
+
op create(@body user: User): User; // Defaults to POST /users
264
264
}
265
265
```
266
266
@@ -317,7 +317,7 @@ paths:
317
317
318
318
[Decorators](https://typespec.io/docs/language-basics/decorators) in TypeSpec add metadata to models, operations, and interfaces. They start with the `@` symbol followed by the decorator name. Here's an example of the `@doc` decorator:
319
319
320
-
```typescript filename="main.tsp" mark=1,3,6,9
320
+
```typespec filename="main.tsp" mark=1,3,6,9
321
321
@doc("A user in the system")
322
322
model User {
323
323
@doc("The unique identifier of the user")
@@ -395,7 +395,7 @@ Open the `main.tsp` file in a text editor and write the TypeSpec specification.
395
395
396
396
Here's an example of a complete TypeSpec file for a Train Travel API:
397
397
398
-
```typescript
398
+
```typespec
399
399
import "@typespec/http";
400
400
import "@typespec/openapi";
401
401
import "@typespec/openapi3";
@@ -646,7 +646,7 @@ Let's break down some of the key features of this TypeSpec file:
646
646
647
647
The file starts by importing necessary TypeSpec modules:
648
648
649
-
```typescript
649
+
```typespec
650
650
import "@typespec/http";
651
651
import "@typespec/openapi";
652
652
import "@typespec/openapi3";
@@ -661,7 +661,7 @@ These modules extend TypeSpec's capabilities for HTTP APIs and OpenAPI generatio
661
661
662
662
The `TrainTravelAPI` namespace is decorated with several metadata decorators:
663
663
664
-
```typescript
664
+
```typespec
665
665
@service(#{ title: "Train Travel API" })
666
666
@info(#{
667
667
version: "1.2.1",
@@ -687,7 +687,7 @@ namespace TrainTravelAPI;
687
687
688
688
TypeSpec supports various validation decorators for model properties:
689
689
690
-
```typescript
690
+
```typespec
691
691
/** A train station. */
692
692
model Station {
693
693
/** Unique identifier for the station. */
@@ -714,7 +714,7 @@ The `@format` decorator adds format annotations (which some OpenAPI tools may ch
714
714
715
715
Operations can return different response types using union types:
716
716
717
-
```typescript
717
+
```typespec
718
718
op `get-stations`(...params):
719
719
| {
720
720
@body body: {
@@ -757,7 +757,7 @@ Using multiple examples like this requires OpenAPI v3.1 or later.
757
757
758
758
The `Parameters` namespace defines reusable parameter models:
759
759
760
-
```typescript
760
+
```typespec
761
761
namespace Parameters {
762
762
model page {
763
763
/** The page number to return */
@@ -781,7 +781,7 @@ TypeSpec supports polymorphism through unions with the `@oneOf` decorator, which
781
781
782
782
Here's an example from the Train Travel API showing how to model payment sources that can be either a card or a bank account:
783
783
784
-
```typescript
784
+
```typespec
785
785
/** Card payment source details. */
786
786
model CardPaymentSource {
787
787
object?: "card";
@@ -936,10 +936,11 @@ options:
936
936
"@typespec/openapi3":
937
937
emitter-output-dir: "{output-dir}/schema"
938
938
openapi-versions:
939
+
- 3.1.0
939
940
- 3.2.0
940
941
```
941
942
942
-
This will configure TypeSpec to emit OpenAPI 3.2 specifically, which is a newer version of OpenAPI supported by both TypeSpec and Speakeasy. For an older version, change the `openapi-versions` value to `3.1.0`.
943
+
This will configure TypeSpec to output both the more compatible OpenAPI v3.1, as well as the latest and greatest OpenAPI v3.2. This newer version is supported by TypeSpec and Speakeasy, and if you have older tools that need the more compatible version why not use both.
943
944
944
945
Now run the TypeSpec compiler in the project root to generate the OpenAPI document:
945
946
@@ -1138,7 +1139,7 @@ TypeSpec allows adding OpenAPI extensions using the `@extension` decorator. This
1138
1139
1139
1140
To add retry logic to operations, add the Speakeasy `x-speakeasy-retries` extension to the TypeSpec specification:
1140
1141
1141
-
```typescript
1142
+
```typespec
1142
1143
@tag("Stations")
1143
1144
@route("/stations")
1144
1145
@get
@@ -1182,6 +1183,23 @@ paths:
1182
1183
retryConnectionErrors: true
1183
1184
```
1184
1185
1186
+
Or, the extension can be added at the namespace level:
1187
+
1188
+
```typespec name="main.tsp"
1189
+
@extension("x-speakeasy-retries", #{
1190
+
strategy: "backoff",
1191
+
backoff: #{
1192
+
initialInterval: 500,
1193
+
maxInterval: 60000,
1194
+
maxElapsedTime: 3600000,
1195
+
exponent: 1.5,
1196
+
},
1197
+
statusCodes: ["5XX"],
1198
+
retryConnectionErrors: true
1199
+
})
1200
+
namespace TrainTravelAPI;
1201
+
```
1202
+
1185
1203
Similar extensions can be added for other Speakeasy features like [pagination](/docs/customize-sdks/pagination), [error handling](/docs/customize-sdks/error-handling), and more.
1186
1204
1187
1205
### Step 8: Generate an SDK from the OpenAPI Document
@@ -1220,17 +1238,10 @@ The `speakeasy run` command uses the existing Speakeasy configuration to regener
1220
1238
1221
1239
## Limitations of TypeSpec
1222
1240
1223
-
While TypeSpec is a powerful tool for generating OpenAPI documents, there are some limitations to be aware of when using it with Speakeasy.
1224
-
1225
-
### 1. No Extensions at the Namespace Level
1226
-
1227
-
The `x-speakeasy-retries` extension cannot be added at the namespace level in the TypeSpec specification, even though Speakeasy supports this extension at the operation level.
1228
-
1229
-
The TypeSpec documentation on the [@extension](https://typespec.io/docs/libraries/openapi/reference/decorators#@TypeSpec.OpenAPI.extension) decorator does not mention any restrictions on where extensions can be applied, so this may be a bug or an undocumented limitation.
1241
+
An earlier version of this guide had a handful of concerns, but TypeSpec has progressed a long way in a short time, and now there is just the one problem we currently have.
1230
1242
1231
-
To work around this limitation, the `x-speakeasy-retries` extension can be added directly to the OpenAPI document using an overlay, as shown in the previous example, or by adding it to each operation individually in the TypeSpec specification**.**
1232
1243
1233
-
### 2. No Support for Webhooks or Callbacks
1244
+
### No Support for Webhooks or Callbacks
1234
1245
1235
1246
TypeSpec [does not yet support webhooks or callbacks](https://github.com/microsoft/typespec/issues/4736), which are common in modern APIs. This means webhook operations or callback URLs cannot be defined in a TypeSpec specification and OpenAPI documents cannot be generated for them.
0 commit comments