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 17 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
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[];
```
15 changes: 15 additions & 0 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
40 changes: 25 additions & 15 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 @@ -375,11 +375,7 @@ op list(

### `@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 +389,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` | Relative route path. Cannot include query parameters. |
| 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): Widget[];
@route("/files{?select,filter}") op listFullUriTemplateselect?: string, filter?: string): Widget[];
```

### `@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
40 changes: 25 additions & 15 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 @@ -423,11 +423,7 @@ op list(

#### `@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 +437,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` | Relative route path. Cannot include query parameters. |
| 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): Widget[];
@route("/files{?select,filter}") op listFullUriTemplateselect?: string, filter?: string): Widget[];
```

#### `@server`
Expand Down
42 changes: 30 additions & 12 deletions packages/http/generated-defs/TypeSpec.Http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ import type {
Type,
} from "@typespec/compiler";

export interface QueryOptions {
readonly name?: string;
readonly explode?: boolean;
readonly format?: "multi" | "csv" | "ssv" | "tsv" | "simple" | "form" | "pipes";
timotheeguerin marked this conversation as resolved.
Show resolved Hide resolved
}

export interface PathOptions {
readonly name?: string;
readonly explode?: boolean;
readonly style?: "simple" | "label" | "matrix" | "fragment" | "path";
readonly allowReserved?: boolean;
}

/**
* Specify the status code for this response. Property type must be a status code integer or a union of status code integer.
*
Expand Down Expand Up @@ -73,13 +86,13 @@ export type HeaderDecorator = (
export type QueryDecorator = (
context: DecoratorContext,
target: ModelProperty,
queryNameOrOptions?: Type
queryNameOrOptions?: string | QueryOptions
) => void;

/**
* Explicitly specify that this property is to be interpolated as a path parameter.
*
* @param paramName Optional name of the parameter in the url template.
* @param paramNameOrOptions Optional name of the parameter in the uri template or options.
* @example
* ```typespec
* @route("/read/{explicit}/things/{implicit}")
Expand All @@ -89,7 +102,7 @@ export type QueryDecorator = (
export type PathDecorator = (
context: DecoratorContext,
target: ModelProperty,
paramName?: string
paramNameOrOptions?: string | PathOptions
) => void;

/**
Expand Down Expand Up @@ -260,20 +273,25 @@ export type IncludeInapplicableMetadataInPayloadDecorator = (
) => void;

/**
* 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.
*
* @param path Relative route path. Cannot include query parameters.
* @param options Set of parameters used to configure the route. Supports `{shared: true}` which indicates that the route may be shared by several operations.
* @example
* @param options _DEPRECATED_ Set of parameters used to configure the route. Supports `{shared: true}` which indicates that the route may be shared by several operations.
* @example Simple path parameter
*
* ```typespec
* @route("/widgets")
* op getWidget(@path id: string): Widget;
* @route("/widgets/{id}") op getWidget(@path id: string): Widget;
* ```
* @example Reserved characters
* ```typespec
* @route("/files{+path}") op getFile(@path path: string): bytes;
* ```
* @example Query parameter
* ```typespec
* @route("/files") op list(select?: string, filter?: string): Widget[];
* @route("/files{?select,filter}") op listFullUriTemplateselect?: string, filter?: string): Widget[];
* ```
*/
export type RouteDecorator = (
Expand Down
Loading
Loading