@nxgt/datasource-rest 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +72 -3
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -4,9 +4,6 @@ An Apollo-style REST datasource over `openapi-fetch`: auth forwarding, caching
4
4
  and error translation, so a GraphQL resolver can call a REST service with the
5
5
  same typed client the REST apps use.
6
6
 
7
- Errors come back as `CustomException` from `@nxgt/shared-exceptions`, so a
8
- downstream 404 surfaces as a `NotFound` rather than a transport failure.
9
-
10
7
  ## Install
11
8
 
12
9
  ```bash
@@ -16,3 +13,75 @@ bun add @nxgt/datasource-rest
16
13
  Public on npmjs; no token needed to install. TypeScript is a peer, pinned to
17
14
  `^6.0.3` across every `@nxgt/*` package — the set is unsatisfiable if one of
18
15
  them widens it.
16
+
17
+ ## Usage
18
+
19
+ ```ts
20
+ import { RESTDataSource, errorToException } from '@nxgt/datasource-rest';
21
+ import createClient from '@nxgt/shared-hono/openapi-fetch';
22
+
23
+ const client = createClient<paths>({ baseUrl: env.BOOKMARKS_API_URL });
24
+
25
+ const bookmarks = new RESTDataSource({
26
+ client,
27
+ authOptions: { token: () => getAccessToken() },
28
+ cacheOptions: { ttl: 5_000 },
29
+ });
30
+
31
+ const { data } = await bookmarks.get('/bookmarks/{id}', {
32
+ params: { path: { id } },
33
+ });
34
+ ```
35
+
36
+ `get` / `post` / `put` / `patch` / `delete` / `head` / `options` / `trace` are
37
+ the client's methods, rebound. Auth and cache are `openapi-fetch` middleware
38
+ installed in the constructor, cache first, then auth.
39
+
40
+ ## Auth middleware
41
+
42
+ ```ts
43
+ authOptions: {
44
+ token: string | (() => Promise<string>),
45
+ shouldUseToken?: (request: Request) => boolean,
46
+ }
47
+ ```
48
+
49
+ The thunk is called per request. `shouldUseToken` skips the header on the
50
+ requests you name. No `token` means the middleware is a no-op.
51
+
52
+ ## Cache middleware
53
+
54
+ In-process `Map`, keyed by `method:url`. Default TTL is five minutes. GET
55
+ (and any other non-POST) responses that are `ok` are stored. POST is cached
56
+ only when `shouldCachePostRequest` says so — the default is "the URL contains
57
+ `/search`".
58
+
59
+ This is a process cache, not Redis. Two instances of the datasource do not
60
+ share it.
61
+
62
+ ## Errors
63
+
64
+ `errorToException(error, response)` maps HTTP status to `CustomException`:
65
+
66
+ | Status | `ErrorCode` |
67
+ | --- | --- |
68
+ | 401 | `Unauthenticated` |
69
+ | 403 | `Forbidden` |
70
+ | 404 | `NotFound` |
71
+ | 500 | `InternalServerError` |
72
+ | other | `BadRequest` |
73
+
74
+ A downstream 404 is `NotFound`, not a transport failure. Catch
75
+ `CustomException`, not an error named after the HTTP library.
76
+
77
+ `relayPaginate(data)` turns a REST `{ data, metadata }` page into a Relay
78
+ `{ edges, pageInfo }` connection, using `item.id` as the cursor.
79
+
80
+ ## Things that bite
81
+
82
+ - **The cache is per process and unbounded except by TTL.** Do not point it at
83
+ an endpoint that varies by caller unless `shouldUseToken` / the URL already
84
+ distinguish them.
85
+ - **`authOptions.token` as a thunk is not awaited by the middleware today.**
86
+ Pass a string, or a thunk that returns a string synchronously, until that
87
+ is a real `async` `onRequest`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxgt/datasource-rest",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -38,8 +38,8 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "lodash": "^4.18.1",
41
- "@nxgt/shared": "^1.0.1",
42
- "@nxgt/shared-exceptions": "^1.0.1",
41
+ "@nxgt/shared": "^1.0.2",
42
+ "@nxgt/shared-exceptions": "^1.0.2",
43
43
  "openapi-fetch": "^0.17.0"
44
44
  },
45
45
  "devDependencies": {