Skip to content

Commit 33ed38c

Browse files
committed
Extended documentation
1 parent 8d6e954 commit 33ed38c

14 files changed

Lines changed: 666 additions & 6 deletions

File tree

docs/.pages

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ nav:
33
- introduction.md
44
- getting-started
55
- endpoints
6+
- serializers
67
- error-handling
78
- link-handling
89
- code-generation

docs/endpoints/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ TypedRest provides a number of endpoint types modelling common REST patterns. Mo
3030
- [Streaming endpoint](reactive/streaming.md) - stream of entities via persistent connection
3131
- [Streaming Collection endpoint](reactive/streaming-collection.md) - collection of entities observable as append-only stream
3232

33-
The constructors of all endpoints except entry endpoints take a `referrer` parameter. This is uses to inherit relative URI bases and configuration such as [error handling](../error-handling/index.md) and [link handling](../link-handling/index.md).
33+
The constructors of all endpoints (except entry endpoints) take a `referrer` parameter. This is used to inherit [relative URI bases](../link-handling/index.md), [serializers](../serializers/index.md) and [error handling](../error-handling/index.md).

docs/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ TypedRest helps you build type-safe, fluent-style REST API clients. Common REST
115115
[Endpoints](endpoints/index.md)
116116
: Documentation for all endpoint types provided by TypedRest.
117117

118+
[Serializers](serializers/index.md)
119+
: How to convert objects to and from the wire format (e.g., JSON).
120+
118121
[Error handling](error-handling/index.md)
119122
: How to handle API errors with TypedRest.
120123

docs/link-handling/.pages

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
nav:
2+
- index.md
3+
- relative-uris.md
4+
- uri-templates.md
5+
- link-header.md
6+
- hal.md
7+
- serializers.md

docs/link-handling/hal.md

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# HAL (Hypertext Application Language)
2+
3+
TypedRest supports extracting links from response bodies using the [HAL specification](https://datatracker.ietf.org/doc/html/draft-kelly-json-hal). HAL provides a consistent format for embedding links and embedded resources within JSON responses.
4+
5+
## HAL format
6+
7+
HAL adds a `_links` object to JSON responses containing links organized by relation type:
8+
9+
```json
10+
{
11+
"id": 123,
12+
"name": "John Doe",
13+
"_links": {
14+
"self": { "href": "/users/123" },
15+
"orders": { "href": "/users/123/orders" },
16+
"search": { "href": "/users/{id}", "templated": true }
17+
}
18+
}
19+
```
20+
21+
## Content Type
22+
23+
TODO: Check the content type is actually used
24+
25+
TypedRest recognizes HAL responses by the `application/hal+json` content type:
26+
27+
```
28+
Content-Type: application/hal+json
29+
```
30+
31+
When this content type is present, TypedRest automatically parses the `_links` object and makes the links available through the standard link resolution methods.
32+
33+
## Using HAL links
34+
35+
After receiving a HAL response, you can resolve links just like with HTTP Link headers:
36+
37+
TODO: Check code samples
38+
39+
=== "C#"
40+
41+
```csharp
42+
await endpoint.ReadAsync();
43+
44+
// Resolve a single link
45+
Uri ordersUri = endpoint.Link("orders");
46+
47+
// Resolve a templated link
48+
Uri userUri = endpoint.LinkTemplate("search", new { id = "456" });
49+
```
50+
51+
=== "TypeScript"
52+
53+
```typescript
54+
await endpoint.read();
55+
56+
// Resolve a single link
57+
const ordersUri = endpoint.link("orders");
58+
59+
// Resolve a templated link
60+
const userUri = endpoint.linkTemplate("search", { id: "456" });
61+
```
62+
63+
## Multiple links
64+
65+
HAL supports multiple links for the same relation type using an array:
66+
67+
```json
68+
{
69+
"_links": {
70+
"item": [
71+
{ "href": "/items/1", "title": "First Item" },
72+
{ "href": "/items/2", "title": "Second Item" }
73+
]
74+
}
75+
}
76+
```
77+
78+
Retrieve all links with `GetLinks`:
79+
80+
TODO: Check code samples
81+
82+
=== "C#"
83+
84+
```csharp
85+
var items = endpoint.GetLinks("item");
86+
foreach (var (uri, title) in items)
87+
{
88+
Console.WriteLine($"{title}: {uri}");
89+
}
90+
```
91+
92+
=== "TypeScript"
93+
94+
```typescript
95+
const items = endpoint.getLinks("item");
96+
for (const { uri, title } of items) {
97+
console.log(`${title}: ${uri}`);
98+
}
99+
```
100+
101+
## Templated links
102+
103+
HAL links can be marked as [templates](uri-templates.md) with the `templated` property:
104+
105+
```json
106+
{
107+
"_links": {
108+
"find": {
109+
"href": "/users{?name,email}",
110+
"templated": true
111+
}
112+
}
113+
}
114+
```
115+
116+
TODO: Check code samples
117+
118+
=== "C#"
119+
120+
```csharp
121+
var findUri = endpoint.LinkTemplate("find", new { name = "John", email = "john@example.com" });
122+
// Result: /users?name=John&email=john%40example.com
123+
```
124+
125+
=== "TypeScript"
126+
127+
```typescript
128+
const findUri = endpoint.linkTemplate("find", { name: "John", email: "john@example.com" });
129+
// Result: /users? name=John&email=john%40example.com
130+
```

docs/link-handling/index.md

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,26 @@
11
# Link handling
22

3-
TypedRest supports a variety of different links:
3+
TypedRest supports a variety of different ways to establish links between [endpoints](../endpoints/index.md):
44

5-
- Hard-coded relative URIs between [endpoints](../endpoints/index.md)
6-
- Links transmitted via the HTTP Link Header
7-
- Links encoded in resources via HAL
8-
- URI templates
5+
- [Hard-coded relative URIs](relative-uris.md)
6+
- [URI templates](uri-templates.md) for dynamic URL construction
7+
- [Links via HTTP Link Header](link-header.md) transmitted in response headers
8+
- [Links encoded in resources via HAL](hal.md) for hypermedia-driven APIs
9+
10+
## Link resolution
11+
12+
All endpoints provide methods for resolving links:
13+
14+
=== "C#"
15+
16+
- `GetLinks(rel)` - Resolves all links with a specific relation type
17+
- `Link(rel)` - Resolves a single link with a specific relation type
18+
- `LinkTemplate(rel, variables)` - Resolves a link template with variables
19+
20+
=== "TypeScript"
21+
22+
- `getLinks(rel)` - Resolves all links with a specific relation type
23+
- `link(rel)` - Resolves a single link with a specific relation type
24+
- `linkTemplate(rel, variables)` - Resolves a link template with variables
25+
26+
These methods use cached data from the last response. On cache miss, they perform a lazy lookup using HTTP `HEAD`.

docs/link-handling/link-header.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# HTTP Link header
2+
3+
TypedRest can extract links from HTTP `Link` headers as defined in [RFC 8288](https://tools.ietf. org/html/rfc8288). This enables HATEOAS-style navigation where the server provides links to related resources in response headers.
4+
5+
## Header format
6+
7+
The HTTP `Link` header follows this format:
8+
9+
```
10+
Link: <target-uri>; rel="relation-type"; title="optional title"
11+
```
12+
13+
Multiple links can be specified in a single header, separated by commas:
14+
15+
```
16+
Link: <http://example.com/users>; rel=collection, <http://example.com/user/123>; rel=self
17+
```
18+
19+
## Extracting links
20+
21+
TypedRest automatically extracts links from response headers after each request. You can then resolve them:
22+
23+
TODO: Check code samples
24+
25+
=== "C#"
26+
27+
```csharp
28+
// Perform a request
29+
await endpoint.ReadAsync();
30+
31+
// Get all links with a specific relation type
32+
var links = endpoint.GetLinks("collection");
33+
foreach (var (uri, title) in links)
34+
{
35+
Console.WriteLine($"URI: {uri}, Title: {title}");
36+
}
37+
38+
// Get a single link
39+
Uri collectionUri = endpoint. Link("collection");
40+
```
41+
42+
=== "TypeScript"
43+
44+
```typescript
45+
// Perform a request
46+
await endpoint.read();
47+
48+
// Get all links with a specific relation type
49+
const links = endpoint.getLinks("collection");
50+
for (const { uri, title } of links) {
51+
console.log(`URI: ${uri}, Title: ${title}`);
52+
}
53+
54+
// Get a single link
55+
const collectionUri = endpoint.link("collection");
56+
```
57+
58+
## Templated links
59+
60+
TypedRest extends the standard Link header format to support [URI templates](uri-templates.md). Templates are indicated with `templated=true`:
61+
62+
```
63+
Link: </users/{id}>; rel=user; templated=true
64+
```
65+
66+
This is a non-standard extension, but it allows servers to provide dynamic link templates via headers without needing HAL or another hypermedia format in the response body.
67+
68+
=== "C#"
69+
70+
```csharp
71+
// Server response:
72+
// Link: </users/{id}>; rel=user; templated=true
73+
74+
var userUri = endpoint.LinkTemplate("user", new { id = "123" });
75+
// Result: http://example.com/users/123
76+
```
77+
78+
=== "TypeScript"
79+
80+
```typescript
81+
// Server response:
82+
// Link: </users/{id}>; rel=user; templated=true
83+
84+
const userUri = endpoint.linkTemplate("user", { id: "123" });
85+
// Result: http://example.com/users/123
86+
```
87+
88+
## Link header attributes
89+
90+
The following attributes are supported:
91+
92+
| Attribute | Description |
93+
|--------------|----------------------------------------------------|
94+
| `rel` | The relation type (required) |
95+
| `title` | Human-readable title for the link (optional) |
96+
| `templated` | Indicates a URI template when set to `true` (non-standard) |

0 commit comments

Comments
 (0)