Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs for Blitz RPC endpoint to the app directory #860

Merged
merged 22 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 163 additions & 1 deletion app/pages/docs/auth-server.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,104 @@ 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 })
```

##### Signature
siddhsuresh marked this conversation as resolved.
Show resolved Hide resolved

##### Arguments

- `handlers: { [method: string]: Handler })` - An object of handlers where
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all the list formats seem broken

the key is the HTTP method and the value is the handler function.

```ts
type Handler = (
request: Request,
params: Record<string, string>,
ctx: { session: SessionContext }
) => Promise<Response>
```

##### 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`:
Expand Down Expand Up @@ -216,3 +313,68 @@ export const updateUserRole = async (
await setPublicDataForUser(userId, { role })
}
```

<Card type="note">
The following methods are meant for internal usage or for advanced use
cases. They are not needed for general use.
</Card>

## `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<string, string>) {
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
92 changes: 83 additions & 9 deletions app/pages/docs/rpc-config.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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?: {
/**
Expand All @@ -99,32 +101,104 @@ logging?: {
disablelevel?: "debug" | "info"
}
```

<Card type="note">
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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list formatting is broken

siddhsuresh marked this conversation as resolved.
Show resolved Hide resolved
</Card>

##### 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}`
return error
},
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`
58 changes: 56 additions & 2 deletions app/pages/docs/rpc-setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down
Loading