Skip to content

Commit

Permalink
Docs for Blitz RPC endpoint to the app directory (#860)
Browse files Browse the repository at this point in the history
* docs

* Update app/pages/docs/rpc-setup.mdx

Co-authored-by: Brandon Bayer <[email protected]>

* fix formatting

* rpcApphanlder config

* mention withBlitzAuth api

* use unknown than any

* push changes

* add api of withBlitzAuth

* eloaborate a bit

* add information on changes to getSession

* cleanup

* cleanup

* lol

* fix

* fix

* add another example

* async

* fixes

* english

* Update app/pages/docs/auth-server.mdx

Co-authored-by: Brandon Bayer <[email protected]>

* Update app/pages/docs/rpc-config.mdx

---------

Co-authored-by: Brandon Bayer <[email protected]>
  • Loading branch information
siddhsuresh and flybayer authored Aug 14, 2024
1 parent 9f04fdf commit a083bb6
Show file tree
Hide file tree
Showing 3 changed files with 303 additions and 12 deletions.
163 changes: 162 additions & 1 deletion app/pages/docs/auth-server.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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<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 +312,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
94 changes: 85 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,106 @@ 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.
</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

0 comments on commit a083bb6

Please sign in to comment.