diff --git a/app/pages/docs/auth-server.mdx b/app/pages/docs/auth-server.mdx index d0729e8b..305e3b45 100644 --- a/app/pages/docs/auth-server.mdx +++ b/app/pages/docs/auth-server.mdx @@ -54,7 +54,103 @@ function PageWithGssp(props: Props) { export default PageWithGssp ``` -## API Routes {#api-routes} +## App Router API Routes {#app-api-routes} + +You can get the session context inside API routes by wrapping it with the +`withBlitzAuth` function exported from `src/blitz-server`: + +```ts +//app/api/logout/route.ts +import { withBlitzAuth } from "app/blitz-server" + +export const POST = withBlitzAuth(async (_request, _params, ctx) => { + const session = ctx.session + await session.$revoke() + return new Response( + JSON.stringify({ + userId: session.userId, + }), + { status: 200 } + ) +}) +``` + +#### `withBlitzAuth` API {#with-blitz-auth-api} + +The function supports both single handler as an input as well as an object +of handlers and has the following signature: + +```ts +function withBlitzAuth(handlers: { [method: string]: Handler }) +``` + + +##### Arguments + +- `handlers: { [method: string]: Handler })` - An object of handlers where + the key is the HTTP method and the value is the handler function. + +```ts +type Handler = ( + request: Request, + params: Record, + ctx: { session: SessionContext } +) => Promise +``` + +##### Returns + +- `{ [method: string]: Handler }` - The wrapper function returns an object + of handlers where the key is the HTTP method and the value is the + handler function wrapped with the session management of `@blitzjs/auth`. + + ##### Example Usage with single handler + +```ts +//app/api/logout/route.ts +import { withBlitzAuth } from "app/blitz-server" + +export const { POST } = withBlitzAuth({ + POST: async (_request, _params, { session }) => { + // logout the user + await session.$revoke() + return new Response( + JSON.stringify({ + userId: session.userId, + }), + { status: 200 } + ) + }, +}) +``` + +##### Example Usage with multiple handlers + +```ts +//app/api/multiple/route.ts +import { withBlitzAuth } from "app/blitz-server" + +export const { GET, POST } = withBlitzAuth({ + GET: async (_request, _params, { session }) => { + return new Response( + JSON.stringify({ + userId: session.userId, + }), + { status: 200 } + ) + }, + POST: async (_request, _params, { session }) => { + return new Response( + JSON.stringify({ + userId: session.userId, + }), + { status: 200 } + ) + }, +}) +``` + +## Pages Router API Routes {#pages-api-routes} You can get the session context inside API routes by wrapping it with the `api` function exported from `src/blitz-server`: @@ -216,3 +312,68 @@ export const updateUserRole = async ( await setPublicDataForUser(userId, { role }) } ``` + + + The following methods are meant for internal usage or for advanced use + cases. They are not needed for general use. + + +## `getSession` {#get-session} + +This function is used internally by Blitz to get the session context from +the request either from an `IncomingMessage` and `ServerResponse` pair or +from a `Request` object. + +#### Arguments + +- `req: IncomingMessage | Request` - The request object from the server. +- `res: ServerResponse | never` - The response object from the server. +- `isRsc: boolean` - A boolean that determines if the request is for a + resource. + +#### Returns + +- `SessionContext` - The session context object. + +## `SessionContext.setSession` {#session-context-set-session} + +This function is used along with [getSession](#get-session) to set the +session context on the response object after the session has been created +or updated. + +#### Arguments + +- `response: Response | ServerResponse` - The response object from the + server. + +#### Returns + +- `void` + +#### Example Usage + +##### With `Request` + +```ts +async function handler(request: Request, params: Record) { + const session = await getSession(request) + const response = await handler(request, params, { session }) + session.setSession(response) + return response +} +``` + +##### With `IncomingMessage` and `ServerResponse` + +```ts +async function handler(req: IncomingMessage, res: ServerResponse) { + const session = await getSession(req, res) + await handler(req, res, { session }) + session.setSession(res) +} +``` + +- `handler` is a function that processes the request and can mutate the + session state +- The `response` | `res` will contain the session state after the handler + has been processed diff --git a/app/pages/docs/rpc-config.mdx b/app/pages/docs/rpc-config.mdx index 13ba84bf..10ddf492 100644 --- a/app/pages/docs/rpc-config.mdx +++ b/app/pages/docs/rpc-config.mdx @@ -75,7 +75,9 @@ module.exports = withBlitz({ ## Logging Setup {#blitz-rpc-logging} -In your `[[...blitz]].ts` api file you can see the following settings in the `rpcHandler` +In your `[[...blitz]].ts` api file you can see the following settings in +the `rpcHandler` + ```ts logging?: { /** @@ -99,19 +101,49 @@ logging?: { disablelevel?: "debug" | "info" } ``` + - Blitz RPC defaults to: - - `verbose` to be true if it not configured. - - The `input` and `resolver completion time` will be logged with the `info` level. - - The `result` and `next.js serialization time` will be logged with the `debug` level. + Blitz RPC defaults to: + - `verbose` to be true if it not configured. + - The `input` and `resolver completion time` will be logged with the + `info` level. + - The `result` and `next.js serialization time` will be + logged with the `debug` level. +##### In App Router (recommended) + +#### `rpcAppHandler`: + +This function acts as the handler for all the queries and mutations in the +next.js app directory. + +#### Arguments: + +- `options` (optional): An object with the following properties: + - `onInvokeError` (optional): A function that will be called when an + error occurs during the invocation of a resolver. + - `formatError` (optional): A function that will be called to format the + error before sending it to the client. + - `logging` (optional): An object with the following properties: + - `allowList` (optional): An array of resolvers that should be logged. + - `blockList` (optional): An array of resolvers that should not be + logged. + - `verbose` (optional): A boolean that determines whether verbose + logging should be enabled. + - `disablelevel` (optional): A string that determines which level of + logging should be disabled. + +#### Returns: + +An object with the handlers that handle the GET, POST, and HEAD requests. -Example: +#### Example: ```ts +// app/api/rpc/[[...blitz]]/route.ts export default api( - rpcHandler({ + rpcAppHandler({ onError: console.log, formatError: (error) => { error.message = `FormatError handler: ${error.message}` @@ -119,12 +151,56 @@ export default api( }, logging: { verbose: true, - blockList: ["getCurrentUser", ...], //just write the resolver name [which is the resolver file name] + blockList: ["getCurrentUser", ...] }, }) ) ``` -This is will enable verbose Blitz RPC logging for all resolvers except the resolvers `getCurrentUser` and others mentioned in the `blockList` +##### In Pages Router + +#### `rpcHandler`: + +This function acts as the handler for all the queries and mutations in the +next.js pages directory. + +#### Arguments: + +- `options` (optional): An object with the following properties: + - `onInvokeError` (optional): A function that will be called when an + error occurs during the invocation of a resolver. + - `formatError` (optional): A function that will be called to format the + error before sending it to the client. + - `logging` (optional): An object with the following properties: + - `allowList` (optional): An array of resolvers that should be logged. + - `blockList` (optional): An array of resolvers that should not be + logged. + - `verbose` (optional): A boolean that determines whether verbose + logging should be enabled. + - `disablelevel` (optional): A string that determines which level of + logging should be disabled. + +#### Returns: + +A function that returns the handler for the RPC API. +```ts +// pages router +// src/pages/api/rpc/[[...blitz]].ts +export default api( + rpcHandler({ + onError: console.log, + formatError: (error) => { + error.message = `FormatError handler: ${error.message}` + return error + }, + logging: { + verbose: true, + blockList: ["getCurrentUser", ...], //just write the resolver name [which is the resolver file name] + }, + }) +) +``` +This is will enable verbose Blitz RPC logging for all resolvers except the +resolvers `getCurrentUser` and others mentioned in the `blockList` diff --git a/app/pages/docs/rpc-setup.mdx b/app/pages/docs/rpc-setup.mdx index 758263f1..8e80b5c8 100644 --- a/app/pages/docs/rpc-setup.mdx +++ b/app/pages/docs/rpc-setup.mdx @@ -9,7 +9,9 @@ sidebar_label: Setup npm i @blitzjs/rpc # yarn add @blitzjs/rpc # pnpm add @blitzjs/rpc ``` -2. Add the following to your `blitz-client.ts` file: +### Client setup {#client-setup} + +Add the following to your `blitz-client.ts` file: ```typescript import { setupClient } from "@blitzjs/next" @@ -47,7 +49,57 @@ export { withBlitz } You can read more about `react-query`'s `QueryClient` options [here](https://react-query.tanstack.com/reference/QueryClient). -3. Add Blitz RPC API Route: +### Server setup {#server-setup} + +Add the following to your `blitz-server.ts` file: + +```ts +const { invoke } = setupBlitzServer({ + plugins: [ + // Other plugins + RpcServerPlugin({ + logging: { + //logging options + }, + onInvokeError(error) { + // Add your custom error handling here + }, + }), + ], +}) + +export { invoke } +``` + +### API setup {#api-setup} + +#### App router (recommended): {#app-router} + +Create an `app/api/rpc/[[...blitz]]` directory in your `src` directory +with a `route.ts` file, and add the following lines: + +##### Standalone Usage + +```ts +// app/api/rpc/[[...blitz]]/route.ts +import { rpcAppHandler } from "@blitzjs/rpc" + +export const { GET, POST, HEAD } = rpcAppHandler() +``` + +##### Blitz Auth Integration + +```ts +// app/api/rpc/[[...blitz]]/route.ts +import { rpcAppHandler } from "@blitzjs/rpc" +import { withBlitzAuth } from "app/blitz-server" + +export const { GET, POST, HEAD } = withBlitzAuth(rpcAppHandler()) +``` + +View [RPC Configurations](/rpc-config) to view the available options. + +#### Pages router: {#pages-router} Create an `pages/api/rpc` directory in your `src` directory with `[[...blitz]].ts` file, and add the following lines: @@ -61,6 +113,8 @@ import { api } from "src/blitz-server" export default api(rpcHandler({})) ``` +View [RPC Configurations](/rpc-config) to view the available options. + --- Follow the [Query Resolvers](/docs/query-resolvers) and