From b2b13eb4908c5a048d024f01a822d9111ced99fe Mon Sep 17 00:00:00 2001 From: Young Jun Joo Date: Tue, 18 Mar 2025 15:37:15 -0400 Subject: [PATCH 1/2] =?UTF-8?q?docs:=20add=20Di=C3=A1taxis=20taxonomy=20la?= =?UTF-8?q?bels=20to=20documentation=20categories?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update sidebars.js with explicit category definitions - Modify how-to guides category description - Create reference/explanation category scaffolding - Align documentation structure with Diátaxis framework --- website/docs/explanation/_category_.json | 9 ++ .../explanation/parsing-codec-chaining.md | 102 ++++++++++++++++++ website/docs/how-to-guides/_category_.json | 1 + website/docs/reference/_category_.json | 9 ++ website/docs/tutorial-basics/_category_.json | 1 + 5 files changed, 122 insertions(+) create mode 100644 website/docs/explanation/_category_.json create mode 100644 website/docs/explanation/parsing-codec-chaining.md create mode 100644 website/docs/reference/_category_.json diff --git a/website/docs/explanation/_category_.json b/website/docs/explanation/_category_.json new file mode 100644 index 00000000..814156b5 --- /dev/null +++ b/website/docs/explanation/_category_.json @@ -0,0 +1,9 @@ +{ + "label": "Explanation", + "documentation_type": "explanation", + "position": 5, + "link": { + "type": "generated-index", + "description": "Conceptual guides explaining api-ts architecture and design decisions." + } +} diff --git a/website/docs/explanation/parsing-codec-chaining.md b/website/docs/explanation/parsing-codec-chaining.md new file mode 100644 index 00000000..a8201d6e --- /dev/null +++ b/website/docs/explanation/parsing-codec-chaining.md @@ -0,0 +1,102 @@ +# Decoding JSON from Headers, Query Parameters, and URL Parameters + +Though we know headers, URL parameters, and query parameters will be received as a +`string` or `string[]` value, due to a limitation in api-ts, `httpRequest` only accepts +codecs that decode values starting from the `unknown` type. Consequently, decoding a +header, URL parameter, or query parameter with a codec like `JsonFromString`, which can +only decode values typed as `string`, will produce a error like: + +``` +Type 'Type' is not assignable to type 'Mixed'. + Types of property 'validate' are incompatible. + Type 'Validate' is not assignable to type 'Validate'. + Type 'unknown' is not assignable to type 'string'. +``` + +There's a straightforward pattern you can use when you have a value typed as `unknown` +but need to decode it with a codec that can only decode a narrower type. This pattern is +called codec chaining: + +```typescript +declare const JsonFromString: t.Type; +declare const t.string: t.Type; + +const myCodec: t.Type = t.string.pipe(JsonFromString); +``` + +Here, `t.string` decodes a value from `unknown` to `string`, and then `JsonFromString` +decodes the same value from `string` to `Json`. + +For example: + +```typescript +import * as t from 'io-ts'; +import { nonEmptyArray, JsonFromString, NumberFromString } from 'io-ts-types'; +import { httpRequest, optional } from '@api-ts/io-ts-http'; + +// Define the Filter type for the JSON string +const Filter = t.type({ + category: t.string, + tags: t.array(t.string), + price: t.type({ + min: t.number, + max: t.number, + }), +}); + +// Define the SearchRequest codec +const SearchRequest = httpRequest({ + params: { + userId: NumberFromString, + }, + query: { + q: t.string, + filter: t.string.pipe(JsonFromString).pipe(Filter), + tags: nonEmptyArray(t.string), + sort: optional(t.string), + }, + headers: { + authorization: t.string, + }, +}); + +// Example request object +const example = { + params: { + userId: '84938492', + }, + query: { + q: 'test', + filter: + '{"category":"books","tags":["crypto","trading"],"price":{"min":10,"max":50}}', + tags: ['tag1', 'tag2', 'tag3'], + sort: 'price', + }, + headers: { + authorization: 'Bearer token', + }, +}; + +// Decode the example +const decoded = SearchRequest.decode(example); +if (decoded._tag === 'Right') { + console.log(decoded); + /* + Expected decoded output + { + userId: 84938492, + q: 'test', + filter: { + category: 'books', + tags: ['crypto', 'trading'], + price: { min: 10, max: 50 }, + }, + tags: ['tag1', 'tag2', 'tag3'], + sort: 'price', + authorization: 'Bearer token', + }; + */ +} else { + console.error('Decoding failed:', decoded.left); +} +``` diff --git a/website/docs/how-to-guides/_category_.json b/website/docs/how-to-guides/_category_.json index 4525a16f..6a7f16f3 100644 --- a/website/docs/how-to-guides/_category_.json +++ b/website/docs/how-to-guides/_category_.json @@ -1,5 +1,6 @@ { "label": "How-To Guides", + "documentation_type": "how-to_guide", "position": 3, "link": { "type": "generated-index", diff --git a/website/docs/reference/_category_.json b/website/docs/reference/_category_.json new file mode 100644 index 00000000..b1bd4795 --- /dev/null +++ b/website/docs/reference/_category_.json @@ -0,0 +1,9 @@ +{ + "label": "Reference", + "documentation_type": "reference", + "position": 4, + "link": { + "type": "generated-index", + "description": "Technical reference documentation for api-ts components" + } +} diff --git a/website/docs/tutorial-basics/_category_.json b/website/docs/tutorial-basics/_category_.json index 34c2b28a..e18acc68 100644 --- a/website/docs/tutorial-basics/_category_.json +++ b/website/docs/tutorial-basics/_category_.json @@ -1,5 +1,6 @@ { "label": "Tutorial - Basics", + "documentation_type": "tutorial", "position": 2, "link": { "type": "generated-index", From 8eb95c071182ca41cc5558078f7688208e01f8ee Mon Sep 17 00:00:00 2001 From: Young Jun Joo Date: Tue, 18 Mar 2025 15:47:14 -0400 Subject: [PATCH 2/2] docs: fix category metadata validation in documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove invalid documentation_type field from category configs - Update category descriptions per Diátaxis framework - Fix Tutorials/How-Tos/Reference/Explanation categories - Align with Docusaurus schema requirements --- website/docs/explanation/_category_.json | 3 +-- website/docs/how-to-guides/_category_.json | 1 - website/docs/reference/_category_.json | 3 +-- website/docs/tutorial-basics/_category_.json | 3 +-- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/website/docs/explanation/_category_.json b/website/docs/explanation/_category_.json index 814156b5..75965541 100644 --- a/website/docs/explanation/_category_.json +++ b/website/docs/explanation/_category_.json @@ -1,9 +1,8 @@ { "label": "Explanation", - "documentation_type": "explanation", "position": 5, "link": { "type": "generated-index", - "description": "Conceptual guides explaining api-ts architecture and design decisions." + "description": "Conceptual guides understanding API design philosophy" } } diff --git a/website/docs/how-to-guides/_category_.json b/website/docs/how-to-guides/_category_.json index 6a7f16f3..4525a16f 100644 --- a/website/docs/how-to-guides/_category_.json +++ b/website/docs/how-to-guides/_category_.json @@ -1,6 +1,5 @@ { "label": "How-To Guides", - "documentation_type": "how-to_guide", "position": 3, "link": { "type": "generated-index", diff --git a/website/docs/reference/_category_.json b/website/docs/reference/_category_.json index b1bd4795..a8e9f72e 100644 --- a/website/docs/reference/_category_.json +++ b/website/docs/reference/_category_.json @@ -1,9 +1,8 @@ { "label": "Reference", - "documentation_type": "reference", "position": 4, "link": { "type": "generated-index", - "description": "Technical reference documentation for api-ts components" + "description": "Technical specifications and API reference documentation" } } diff --git a/website/docs/tutorial-basics/_category_.json b/website/docs/tutorial-basics/_category_.json index e18acc68..b48dd0c6 100644 --- a/website/docs/tutorial-basics/_category_.json +++ b/website/docs/tutorial-basics/_category_.json @@ -1,9 +1,8 @@ { "label": "Tutorial - Basics", - "documentation_type": "tutorial", "position": 2, "link": { "type": "generated-index", - "description": "5 minutes to learn the most important api-ts concepts." + "description": "Hands-on learning experiences for API specification fundamentals" } }