Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for URI templates #3932

Merged
merged 35 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
85f6c13
Initial
timotheeguerin Jul 19, 2024
27b56f8
Basic uri template parsing
timotheeguerin Jul 19, 2024
cc97ec9
Add uri template resolution and keep existing test working
timotheeguerin Jul 22, 2024
0cb48df
Implicit extract
timotheeguerin Jul 22, 2024
451705d
Route progress
timotheeguerin Jul 22, 2024
8cd5317
Rest fix
timotheeguerin Jul 22, 2024
905f248
Fix rest
timotheeguerin Jul 22, 2024
a74b933
Merge branch 'main' into uri-templates
timotheeguerin Jul 22, 2024
8fc3238
Merge branch 'main' into uri-templates
timotheeguerin Jul 23, 2024
e9df1b8
Merge branch 'main' of https://github.com/Microsoft/typespec into uri…
timotheeguerin Jul 24, 2024
36084ec
Some doc fixes
timotheeguerin Jul 24, 2024
2565b9f
Add path parameter tests
timotheeguerin Jul 24, 2024
a392551
Create uri-templates-2024-6-24-20-7-39.md
timotheeguerin Jul 24, 2024
d8d960b
Create uri-templates-2024-6-24-21-37-52.md
timotheeguerin Jul 25, 2024
3653a35
ADd explode support to query
timotheeguerin Jul 25, 2024
0fbfa04
Merge branch 'main' into uri-templates
timotheeguerin Jul 25, 2024
e990691
regen samples
timotheeguerin Jul 25, 2024
b250d05
Update packages/http/lib/decorators.tsp
timotheeguerin Jul 25, 2024
2b1d1dc
regen
timotheeguerin Jul 26, 2024
c38a8d6
Merge branch 'main' of https://github.com/microsoft/typespec into uri…
timotheeguerin Jul 26, 2024
661a1bb
regen docs
timotheeguerin Jul 26, 2024
a981368
Fix CR comments
timotheeguerin Jul 31, 2024
ba26263
Merge branch 'uri-templates' of https://github.com/timotheeguerin/typ…
timotheeguerin Jul 31, 2024
8ef0c75
Merge branch 'main' of https://github.com/Microsoft/typespec into uri…
timotheeguerin Jul 31, 2024
9d20aa7
regen
timotheeguerin Jul 31, 2024
38b8422
keep legacy format
timotheeguerin Aug 2, 2024
6eba177
Fix
timotheeguerin Aug 5, 2024
6ae6919
Merge branch 'main' of https://github.com/Microsoft/typespec into uri…
timotheeguerin Aug 5, 2024
ca098c1
Merge branch 'main' of https://github.com/Microsoft/typespec into uri…
timotheeguerin Aug 5, 2024
6d922f7
Fix
timotheeguerin Aug 5, 2024
cc7f4f3
Merge branch 'main' of https://github.com/Microsoft/typespec into uri…
timotheeguerin Aug 5, 2024
6d950fb
add more tests
timotheeguerin Aug 6, 2024
08fc781
Fixes
timotheeguerin Aug 6, 2024
c9bd8ba
Create uri-templates-2024-7-6-16-39-59.md
timotheeguerin Aug 6, 2024
5522c81
Regen docs
timotheeguerin Aug 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .chronus/changes/uri-templates-2024-6-24-20-7-39.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: feature
packages:
- "@typespec/http"
---

`@route` can now take a uri template as defined by [RFC-6570](https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.3)

```tsp
@route("files{+path}") download(path: string): void;
```
9 changes: 9 additions & 0 deletions .chronus/changes/uri-templates-2024-6-24-21-37-52.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: feature
packages:
- "@typespec/openapi3"
- "@typespec/rest"
---

Add support for URI templates in routes
7 changes: 7 additions & 0 deletions .chronus/changes/uri-templates-2024-6-25-9-3-39-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: deprecation
packages:
- "@typespec/http"
---

API deprecation: `HttpOperation#pathSegments` is deprecated. Use `HttpOperation#uriTemplate` instead.
13 changes: 13 additions & 0 deletions .chronus/changes/uri-templates-2024-6-25-9-3-39.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
changeKind: deprecation
packages:
- "@typespec/http"
---

Deprecated `@query({format: })` option. Use `@query(#{explode: true})` instead of `form` or `multi` format. Previously `csv`/`simple` is the default now.
timotheeguerin marked this conversation as resolved.
Show resolved Hide resolved
Decorator is also expecting an object value now instead of a model. A deprecation warning with a codefix will help migrating.

```diff
- @query({format: "form"}) select: string[];
+ @query(#{explode: true}) select: string[];
```
24 changes: 20 additions & 4 deletions docs/libraries/http/reference/data-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,21 @@ model TypeSpec.Http.PasswordFlow
| refreshUrl? | `string` | the refresh URL |
| scopes? | `string[]` | list of scopes for the credential |

### `PathOptions` {#TypeSpec.Http.PathOptions}

```typespec
model TypeSpec.Http.PathOptions
```

#### Properties

| Name | Type | Description |
| -------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name? | `string` | Name of the parameter in the uri template. |
| explode? | `boolean` | When interpolating this parameter in the case of array or object expand each value using the given style.<br />Equivalent of adding `*` in the path parameter as per [RFC-6570](https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.3) |
| style? | `"simple" \| "label" \| "matrix" \| "fragment" \| "path"` | Different interpolating styles for the path parameter.<br />- `simple`: No special encoding.<br />- `label`: Using `.` separator.<br />- `matrix`: `;` as separator.<br />- `fragment`: `#` as separator.<br />- `path`: `/` as separator. |
| allowReserved? | `boolean` | When interpolating this parameter do not encode reserved characters.<br />Equivalent of adding `+` in the path parameter as per [RFC-6570](https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.3) |

### `PlainData` {#TypeSpec.Http.PlainData}

Produces a new model with the same properties as T, but with `@query`,
Expand Down Expand Up @@ -495,10 +510,11 @@ model TypeSpec.Http.QueryOptions

#### Properties

| Name | Type | Description |
| ------- | --------------------------------------------------------------------- | --------------------------------------------------------- |
| name? | `string` | Name of the query when included in the url. |
| format? | `"multi" \| "csv" \| "ssv" \| "tsv" \| "simple" \| "form" \| "pipes"` | Determines the format of the array if type array is used. |
| Name | Type | Description |
| -------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| name? | `string` | Name of the query when included in the url. |
| explode? | `boolean` | If true send each value in the array/object as a separate query parameter.<br />Equivalent of adding `*` in the path parameter as per [RFC-6570](https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.3)<br /><br />\| Style \| Explode \| Uri Template \| Primitive value id = 5 \| Array id = [3, 4, 5] \| Object id = {"role": "admin", "firstName": "Alex"} \|<br />\| ------ \| ------- \| -------------- \| ---------------------- \| ----------------------- \| -------------------------------------------------- \|<br />\| simple \| false \| `/users{?id}` \| `/users?id=5` \| `/users?id=3,4,5` \| `/users?id=role,admin,firstName,Alex` \|<br />\| simple \| true \| `/users{?id*}` \| `/users?id=5` \| `/users?id=3&id=4&id=5` \| `/users?role=admin&firstName=Alex` \| |
| format? | `"multi" \| "csv" \| "ssv" \| "tsv" \| "simple" \| "form" \| "pipes"` | Determines the format of the array if type array is used.<br />**DEPRECATED**: use explode: true instead of `multi` or `@encode` |

### `Response` {#TypeSpec.Http.Response}

Expand Down
56 changes: 30 additions & 26 deletions docs/libraries/http/reference/decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ None
Explicitly specify that this property is to be interpolated as a path parameter.

```typespec
@TypeSpec.Http.path(paramName?: valueof string)
@TypeSpec.Http.path(paramNameOrOptions?: valueof string | TypeSpec.Http.PathOptions)
```

#### Target
Expand All @@ -287,9 +287,9 @@ Explicitly specify that this property is to be interpolated as a path parameter.

#### Parameters

| Name | Type | Description |
| --------- | ---------------- | --------------------------------------------------- |
| paramName | `valueof string` | Optional name of the parameter in the url template. |
| Name | Type | Description |
| ------------------ | --------------------------------------------- | -------------------------------------------------------------- |
| paramNameOrOptions | `valueof string \| TypeSpec.Http.PathOptions` | Optional name of the parameter in the uri template or options. |

#### Examples

Expand Down Expand Up @@ -347,7 +347,7 @@ None
Specify this property is to be sent as a query parameter.

```typespec
@TypeSpec.Http.query(queryNameOrOptions?: string | TypeSpec.Http.QueryOptions)
@TypeSpec.Http.query(queryNameOrOptions?: valueof string | TypeSpec.Http.QueryOptions)
```

#### Target
Expand All @@ -356,30 +356,20 @@ Specify this property is to be sent as a query parameter.

#### Parameters

| Name | Type | Description |
| ------------------ | -------------------------------------- | ------------------------------------------------------------------------------- |
| queryNameOrOptions | `string \| TypeSpec.Http.QueryOptions` | Optional name of the query when included in the url or query parameter options. |
| Name | Type | Description |
| ------------------ | ---------------------------------------------- | ------------------------------------------------------------------------------- |
| queryNameOrOptions | `valueof string \| TypeSpec.Http.QueryOptions` | Optional name of the query when included in the url or query parameter options. |

#### Examples

```typespec
op read(@query select: string, @query("order-by") orderBy: string): void;
op list(
@query({
name: "id",
format: "multi",
})
ids: string[],
): void;
op list(@query(#{ name: "id", explode: true }) ids: string[]): void;
```

### `@route` {#@TypeSpec.Http.route}

Defines the relative route URI for the target operation

The first argument should be a URI fragment that may contain one or more path parameter fields.
If the namespace or interface that contains the operation is also marked with a `@route` decorator,
it will be used as a prefix to the route URI of the operation.
Defines the relative route URI template for the target operation as defined by [RFC 6570](https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.3)

`@route` can only be applied to operations, namespaces, and interfaces.

Expand All @@ -393,16 +383,30 @@ it will be used as a prefix to the route URI of the operation.

#### Parameters

| Name | Type | Description |
| ------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| path | `valueof string` | Relative route path. Cannot include query parameters. |
| options | `{...}` | Set of parameters used to configure the route. Supports `{shared: true}` which indicates that the route may be shared by several operations. |
| Name | Type | Description |
| ------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| path | `valueof string` | |
| options | `{...}` | _DEPRECATED_ Set of parameters used to configure the route. Supports `{shared: true}` which indicates that the route may be shared by several operations. |

#### Examples

##### Simple path parameter

```typespec
@route("/widgets")
op getWidget(@path id: string): Widget;
@route("/widgets/{id}") op getWidget(@path id: string): Widget;
```

##### Reserved characters

```typespec
@route("/files{+path}") op getFile(@path path: string): bytes;
```

##### Query parameter

```typespec
@route("/files") op list(select?: string, filter?: string): Files[];
@route("/files{?select,filter}") op listFullUriTemplate(select?: string, filter?: string): Files[];
```

### `@server` {#@TypeSpec.Http.server}
Expand Down
1 change: 1 addition & 0 deletions docs/libraries/http/reference/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ npm install --save-peer @typespec/http
- [`OkResponse`](./data-types.md#TypeSpec.Http.OkResponse)
- [`OpenIdConnectAuth`](./data-types.md#TypeSpec.Http.OpenIdConnectAuth)
- [`PasswordFlow`](./data-types.md#TypeSpec.Http.PasswordFlow)
- [`PathOptions`](./data-types.md#TypeSpec.Http.PathOptions)
- [`PlainData`](./data-types.md#TypeSpec.Http.PlainData)
- [`QueryOptions`](./data-types.md#TypeSpec.Http.QueryOptions)
- [`Response`](./data-types.md#TypeSpec.Http.Response)
Expand Down
56 changes: 30 additions & 26 deletions packages/http/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ None
Explicitly specify that this property is to be interpolated as a path parameter.

```typespec
@TypeSpec.Http.path(paramName?: valueof string)
@TypeSpec.Http.path(paramNameOrOptions?: valueof string | TypeSpec.Http.PathOptions)
```

##### Target
Expand All @@ -335,9 +335,9 @@ Explicitly specify that this property is to be interpolated as a path parameter.

##### Parameters

| Name | Type | Description |
| --------- | ---------------- | --------------------------------------------------- |
| paramName | `valueof string` | Optional name of the parameter in the url template. |
| Name | Type | Description |
| ------------------ | --------------------------------------------- | -------------------------------------------------------------- |
| paramNameOrOptions | `valueof string \| TypeSpec.Http.PathOptions` | Optional name of the parameter in the uri template or options. |

##### Examples

Expand Down Expand Up @@ -395,7 +395,7 @@ None
Specify this property is to be sent as a query parameter.

```typespec
@TypeSpec.Http.query(queryNameOrOptions?: string | TypeSpec.Http.QueryOptions)
@TypeSpec.Http.query(queryNameOrOptions?: valueof string | TypeSpec.Http.QueryOptions)
```

##### Target
Expand All @@ -404,30 +404,20 @@ Specify this property is to be sent as a query parameter.

##### Parameters

| Name | Type | Description |
| ------------------ | -------------------------------------- | ------------------------------------------------------------------------------- |
| queryNameOrOptions | `string \| TypeSpec.Http.QueryOptions` | Optional name of the query when included in the url or query parameter options. |
| Name | Type | Description |
| ------------------ | ---------------------------------------------- | ------------------------------------------------------------------------------- |
| queryNameOrOptions | `valueof string \| TypeSpec.Http.QueryOptions` | Optional name of the query when included in the url or query parameter options. |

##### Examples

```typespec
op read(@query select: string, @query("order-by") orderBy: string): void;
op list(
@query({
name: "id",
format: "multi",
})
ids: string[],
): void;
op list(@query(#{ name: "id", explode: true }) ids: string[]): void;
```

#### `@route`

Defines the relative route URI for the target operation

The first argument should be a URI fragment that may contain one or more path parameter fields.
If the namespace or interface that contains the operation is also marked with a `@route` decorator,
it will be used as a prefix to the route URI of the operation.
Defines the relative route URI template for the target operation as defined by [RFC 6570](https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.3)

`@route` can only be applied to operations, namespaces, and interfaces.

Expand All @@ -441,16 +431,30 @@ it will be used as a prefix to the route URI of the operation.

##### Parameters

| Name | Type | Description |
| ------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| path | `valueof string` | Relative route path. Cannot include query parameters. |
| options | `{...}` | Set of parameters used to configure the route. Supports `{shared: true}` which indicates that the route may be shared by several operations. |
| Name | Type | Description |
| ------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| path | `valueof string` | |
| options | `{...}` | _DEPRECATED_ Set of parameters used to configure the route. Supports `{shared: true}` which indicates that the route may be shared by several operations. |

##### Examples

###### Simple path parameter

```typespec
@route("/widgets")
op getWidget(@path id: string): Widget;
@route("/widgets/{id}") op getWidget(@path id: string): Widget;
```

###### Reserved characters

```typespec
@route("/files{+path}") op getFile(@path path: string): bytes;
```

###### Query parameter

```typespec
@route("/files") op list(select?: string, filter?: string): Files[];
@route("/files{?select,filter}") op listFullUriTemplate(select?: string, filter?: string): Files[];
```

#### `@server`
Expand Down
Loading
Loading