From f01b8d5d8dfe7c4bf18700f9d1667dae46150098 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Sun, 18 Dec 2022 23:25:46 -0800 Subject: [PATCH] docs: improve docs --- .../content/1.get-started/2.usage/1.simple.md | 30 +------ .../1.get-started/2.usage/2.recommended.md | 30 +------ .../1.get-started/3.client/1.create.md | 53 +++++++++++ .../3.client/2.links/1.httpLink.md | 58 ++++++++++++ .../3.client/2.links/2.httpBatchLink.md | 88 +++++++++++++++++++ .../{3.tips => 4.tips}/1.composables.md | 4 + .../{3.tips => 4.tips}/2.headers.md | 4 + .../{3.tips => 4.tips}/3.authorization.md | 0 .../{3.tips => 4.tips}/4.server-side-calls.md | 0 .../5.aborting-procedures.md | 0 10 files changed, 211 insertions(+), 56 deletions(-) create mode 100644 docs/content/1.get-started/3.client/1.create.md create mode 100644 docs/content/1.get-started/3.client/2.links/1.httpLink.md create mode 100644 docs/content/1.get-started/3.client/2.links/2.httpBatchLink.md rename docs/content/1.get-started/{3.tips => 4.tips}/1.composables.md (87%) rename docs/content/1.get-started/{3.tips => 4.tips}/2.headers.md (88%) rename docs/content/1.get-started/{3.tips => 4.tips}/3.authorization.md (100%) rename docs/content/1.get-started/{3.tips => 4.tips}/4.server-side-calls.md (100%) rename docs/content/1.get-started/{3.tips => 4.tips}/5.aborting-procedures.md (100%) diff --git a/docs/content/1.get-started/2.usage/1.simple.md b/docs/content/1.get-started/2.usage/1.simple.md index 8cb41f1..cf947d2 100644 --- a/docs/content/1.get-started/2.usage/1.simple.md +++ b/docs/content/1.get-started/2.usage/1.simple.md @@ -1,5 +1,5 @@ --- -title: Simple Usage +title: Simple description: tRPC-Nuxt provides first class integration with tRPC. --- @@ -77,10 +77,8 @@ export default createNuxtApiHandler({ Create a strongly-typed plugin using your API's type signature. ```ts [plugins/client.ts] -import { httpBatchLink } from '@trpc/client' -import { createTRPCNuxtClient } from 'trpc-nuxt/client' +import { createTRPCNuxtClient, httpBatchLink } from 'trpc-nuxt/client' import type { AppRouter } from '~/server/trpc/routers' -import { FetchError } from 'ofetch' export default defineNuxtPlugin(() => { /** @@ -91,30 +89,6 @@ export default defineNuxtPlugin(() => { links: [ httpBatchLink({ url: '/api/trpc', - - - /** - * Replace regular `fetch` with a `$fetch` from nuxt - * - * During server-side rendering, calling $fetch to fetch your internal API routes - * will directly call the relevant function (emulating the request), - * saving an additional API call. - * - * @see https://nuxt.com/docs/api/utils/dollarfetch - */ - fetch: (input, options) => - globalThis.$fetch.raw(input.toString(), options) - .catch((e) => { - if (e instanceof FetchError && e.response) - return e.response - - throw e - }) - .then(response => ({ - ...response, - json: () => Promise.resolve(response._data), - })), - }), ], }) diff --git a/docs/content/1.get-started/2.usage/2.recommended.md b/docs/content/1.get-started/2.usage/2.recommended.md index 1e1413f..296cbd8 100644 --- a/docs/content/1.get-started/2.usage/2.recommended.md +++ b/docs/content/1.get-started/2.usage/2.recommended.md @@ -1,5 +1,5 @@ --- -title: Recommended Usage +title: Recommended description: tRPC-Nuxt provides first class integration with tRPC. --- @@ -112,10 +112,8 @@ If you need to split your router into several subrouters, you can implement them Create a strongly-typed plugin using your API's type signature. ```ts [plugins/client.ts] -import { httpBatchLink } from '@trpc/client' -import { createTRPCNuxtClient } from 'trpc-nuxt/client' +import { createTRPCNuxtClient, httpBatchLink } from 'trpc-nuxt/client' import type { AppRouter } from '~/server/trpc/routers' -import { FetchError } from 'ofetch' export default defineNuxtPlugin(() => { /** @@ -126,30 +124,6 @@ export default defineNuxtPlugin(() => { links: [ httpBatchLink({ url: '/api/trpc', - - - /** - * Replace regular `fetch` with a `$fetch` from nuxt - * - * During server-side rendering, calling $fetch to fetch your internal API routes - * will directly call the relevant function (emulating the request), - * saving an additional API call. - * - * @see https://nuxt.com/docs/api/utils/dollarfetch - */ - fetch: (input, options) => - globalThis.$fetch.raw(input.toString(), options) - .catch((e) => { - if (e instanceof FetchError && e.response) - return e.response - - throw e - }) - .then(response => ({ - ...response, - json: () => Promise.resolve(response._data), - })), - }), ], }) diff --git a/docs/content/1.get-started/3.client/1.create.md b/docs/content/1.get-started/3.client/1.create.md new file mode 100644 index 0000000..5555417 --- /dev/null +++ b/docs/content/1.get-started/3.client/1.create.md @@ -0,0 +1,53 @@ +--- +title: Create Nuxt Client +description: tRPC-Nuxt provides first class integration with tRPC. +--- + +# Nuxt client + +The magic of tRPC is making strongly typed API calls without relying on code generation. With full-stack TypeScript projects, you can directly import types from the server into the client! This is a vital part of how tRPC works. + +## Initialize a tRPC client + +Create a typesafe client via a Nuxt [plugin](https://nuxt.com/docs/guide/directory-structure/plugins) with the `createTRPCNuxtClient` method from `trpc-nuxt/client`, and add a `links` array with a [terminating link](https://trpc.io/docs/links#the-terminating-link). If you want to learn more about tRPC links, check out the docs [here](https://trpc.io/docs/links): + +::alert{type="info"} +`createTRPCNuxtClient` extends [createTRPCProxyClient](https://trpc.io/docs/vanilla#initialize-a-trpc-client) and adds a `useQuery` method built on top of [useAsyncData](https://nuxt.com/docs/api/composables/use-async-data). +:: + +```ts [plugins/client.ts] +import { createTRPCNuxtClient, httpBatchLink } from 'trpc-nuxt/client' +import type { AppRouter } from '~/server/trpc/routers' + +export default defineNuxtPlugin(() => { + const client = createTRPCNuxtClient({ + links: [ + httpBatchLink({ + url: '/api/trpc', + }), + ], + }) + + return { + provide: { + client, + }, + } +}) +``` + +As you can see, we passed `AppRouter` as a type argument of `createTRPCNuxtClient`. This returns a strongly typed `client` instance, a proxy that mirrors the structure of your `AppRouter` on the client: + +```vue [pages/index.vue] + +``` diff --git a/docs/content/1.get-started/3.client/2.links/1.httpLink.md b/docs/content/1.get-started/3.client/2.links/1.httpLink.md new file mode 100644 index 0000000..e346599 --- /dev/null +++ b/docs/content/1.get-started/3.client/2.links/1.httpLink.md @@ -0,0 +1,58 @@ +--- +title: HTTP Link +description: httpLink is a terminating link that sends a tRPC operation to a tRPC procedure over HTTP. +--- + +# HTTP Link + +`httpLink` is a [terminating link](https://trpc.io/docs/links#the-terminating-link) that sends a tRPC operation to a tRPC procedure over HTTP. + +`httpLink` supports both POST and GET requests. + +::alert{type="info"} +`httpLink` imported from `trpc-nuxt/client` is a convenience wrapper around the original `httpLink` that replaces regular `fetch` with a [`$fetch`](https://nuxt.com/docs/api/utils/dollarfetch) from Nuxt. It also sets the default headers using [`useRequestHeaders`](https://nuxt.com/docs/api/composables/use-request-headers#userequestheaders). +:: + +## Usage + +You can import and add the `httpLink` to the `links` array as such: + +```ts +import { createTRPCNuxtClient, httpLink } from 'trpc-nuxt/client' +import type { AppRouter } from '~/server/trpc/routers' + +const client = createTRPCNuxtClient({ + links: [ + httpLink({ + url: '/api/trpc', + }), + ], +}) +``` + +## `httpLink` Options + +The `httpLink` function takes an options object that has the `HTTPLinkOptions` shape. + +```ts +export interface HTTPLinkOptions { + url: string; + /** + * Select headers to pass to `useRequestHeaders`. + */ + pickHeaders?: string[]; + /** + * Add ponyfill for fetch. + */ + fetch?: typeof fetch; + /** + * Add ponyfill for AbortController + */ + AbortController?: typeof AbortController | null; + /** + * Headers to be set on outgoing requests or a callback that of said headers + * @link http://trpc.io/docs/v10/header + */ + headers?: HTTPHeaders | (() => HTTPHeaders | Promise); +} +``` diff --git a/docs/content/1.get-started/3.client/2.links/2.httpBatchLink.md b/docs/content/1.get-started/3.client/2.links/2.httpBatchLink.md new file mode 100644 index 0000000..03d4df6 --- /dev/null +++ b/docs/content/1.get-started/3.client/2.links/2.httpBatchLink.md @@ -0,0 +1,88 @@ +--- +title: HTTP Batch Link +description: httpBatchLink is a terminating link that batches an array of individual tRPC operations into a single HTTP request that's sent to a single tRPC procedure. +--- + +# HTTP Batch Link + +`httpBatchLink` is a [terminating link](https://trpc.io/docs/links#the-terminating-link) that batches an array of individual tRPC operations into a single HTTP request that's sent to a single tRPC procedure. + +::alert{type="info"} +`httpBatchLink` imported from `trpc-nuxt/client` is a convenience wrapper around the original `httpBatchLink` that replaces regular `fetch` with a [`$fetch`](https://nuxt.com/docs/api/utils/dollarfetch) from Nuxt. It also sets the default headers using [`useRequestHeaders`](https://nuxt.com/docs/api/composables/use-request-headers#userequestheaders). +:: + +## Usage + +You can import and add the `httpBatchLink` to the `links` array as such: + +```ts +import { createTRPCNuxtClient, httpBatchLink } from 'trpc-nuxt/client' +import type { AppRouter } from '~/server/trpc/routers' + +const client = createTRPCNuxtClient({ + links: [ + httpBatchLink({ + url: '/api/trpc', + }), + ], +}) +``` + +After that, you can make use of batching by setting all your procedures in a `Promise.all`. The code below will produce exactly one HTTP request and on the server exactly `one` database query: + +```ts +const somePosts = await Promise.all([ + $client.post.byId.query(1); + $client.post.byId.query(2); + $client.post.byId.query(3); +]) +``` + +## `httpBatchLink` Options + +The `httpBatchLink` function takes an options object that has the `HTTPBatchLinkOptions` shape. + +```ts +export interface HttpBatchLinkOptions extends HTTPLinkOptions { + maxURLLength?: number; +} + +export interface HTTPLinkOptions { + url: string; + /** + * Select headers to pass to `useRequestHeaders`. + */ + pickHeaders?: string[]; + /** + * Add ponyfill for fetch. + */ + fetch?: typeof fetch; + /** + * Add ponyfill for AbortController + */ + AbortController?: typeof AbortController | null; + /** + * Headers to be set on outgoing requests or a callback that of said headers + * @link http://trpc.io/docs/v10/header + */ + headers?: HTTPHeaders | (() => HTTPHeaders | Promise); +} +``` + +## Setting a maximum URL length + +When sending batch requests, sometimes the URL can become too large causing HTTP errors like [413 Payload Too Large](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413), [414 URI Too Long](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/414), and [404 Not Found](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404). The `maxURLLength` option will limit the number of requests that can be sent together in a batch. + +```ts +import { createTRPCNuxtClient, httpBatchLink } from 'trpc-nuxt/client'; +import type { AppRouter } from '~/server/trpc/routers' + +const client = createTRPCNuxtClient({ + links: [ + httpBatchLink({ + url: '/api/trpc', + maxURLLength: 2083, // a suitable size + }), + ], +}); +``` diff --git a/docs/content/1.get-started/3.tips/1.composables.md b/docs/content/1.get-started/4.tips/1.composables.md similarity index 87% rename from docs/content/1.get-started/3.tips/1.composables.md rename to docs/content/1.get-started/4.tips/1.composables.md index 20e7c1a..02929a0 100644 --- a/docs/content/1.get-started/3.tips/1.composables.md +++ b/docs/content/1.get-started/4.tips/1.composables.md @@ -6,6 +6,10 @@ title: Composables It is often useful to wrap functionality of your `@trpc/client` api within other functions. For this purpose, it's necessary to be able to infer input types and output types generated by your `@trpc/server` router. +::alert{type="info"} +[createTRPCNuxtClient](/get-started/client/create) adds a `useQuery` method built on top of [useAsyncData](https://nuxt.com/docs/api/composables/use-async-data/). +:: + ## Inference Helpers `@trpc/server` exports the following helper types to assist with inferring these types from the `AppRouter` exported by your `@trpc/server` router: diff --git a/docs/content/1.get-started/3.tips/2.headers.md b/docs/content/1.get-started/4.tips/2.headers.md similarity index 88% rename from docs/content/1.get-started/3.tips/2.headers.md rename to docs/content/1.get-started/4.tips/2.headers.md index 626840b..1446345 100644 --- a/docs/content/1.get-started/3.tips/2.headers.md +++ b/docs/content/1.get-started/4.tips/2.headers.md @@ -6,6 +6,10 @@ title: Headers We can use the built-in [useRequestHeaders](https://v3.nuxtjs.org/api/composables/use-request-headers/) to set outgoing request headers: +::alert{type="info"} +[createTRPCNuxtClient](/get-started/client/create) has this feature by default. +:: + ```ts [plugins/client.ts] export default defineNuxtPlugin(() => { const headers = useRequestHeaders() diff --git a/docs/content/1.get-started/3.tips/3.authorization.md b/docs/content/1.get-started/4.tips/3.authorization.md similarity index 100% rename from docs/content/1.get-started/3.tips/3.authorization.md rename to docs/content/1.get-started/4.tips/3.authorization.md diff --git a/docs/content/1.get-started/3.tips/4.server-side-calls.md b/docs/content/1.get-started/4.tips/4.server-side-calls.md similarity index 100% rename from docs/content/1.get-started/3.tips/4.server-side-calls.md rename to docs/content/1.get-started/4.tips/4.server-side-calls.md diff --git a/docs/content/1.get-started/3.tips/5.aborting-procedures.md b/docs/content/1.get-started/4.tips/5.aborting-procedures.md similarity index 100% rename from docs/content/1.get-started/3.tips/5.aborting-procedures.md rename to docs/content/1.get-started/4.tips/5.aborting-procedures.md