Skip to content

Commit 283e153

Browse files
authored
docs: improve "Dedupe Middleware" (#260)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Refactor** - Streamlined backend middleware to optimize database connection reuse and reduce redundant initialization. - Enhanced authentication handling by refining session management for more reliable user validation. Overall, these updates improve backend efficiency and stability to deliver a smoother, more consistent application experience. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 6c1c681 commit 283e153

File tree

7 files changed

+70
-92
lines changed

7 files changed

+70
-92
lines changed

apps/content/docs/best-practices/dedupe-middleware.md

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ declare function connectDb(): Promise<'a_fake_db'>
2828
const dbProvider = os
2929
.$context<{ db?: Awaited<ReturnType<typeof connectDb>> }>()
3030
.middleware(async ({ context, next }) => {
31-
if (context.db) {
32-
return next({ context: { db: context.db } })
33-
}
31+
/**
32+
* If db already exists, skip the connection.
33+
*/
34+
const db = context.db ?? await connectDb() // [!code highlight]
3435

35-
return next({ context: { db: await connectDb() } })
36+
return next({ context: { db } })
3637
})
3738
```
3839

@@ -45,22 +46,27 @@ declare function connectDb(): Promise<'a_fake_db'>
4546
const dbProvider = os
4647
.$context<{ db?: Awaited<ReturnType<typeof connectDb>> }>()
4748
.middleware(async ({ context, next }) => {
48-
if (context.db) {
49-
return next({ context: { db: context.db } })
50-
}
51-
const db = await connectDb()
49+
const db = context.db ?? await connectDb()
50+
5251
return next({ context: { db } })
5352
})
5453
// ---cut---
5554
const foo = os.use(dbProvider).handler(({ context }) => 'Hello World')
5655

5756
const bar = os.use(dbProvider).handler(({ context }) => {
58-
const result = call(foo, 'input', { context })
57+
/**
58+
* Now when you call foo, the dbProvider middleware no need to connect to the database again.
59+
*/
60+
const result = call(foo, 'input', { context }) // [!code highlight]
61+
5962
return 'Hello World'
6063
})
6164

65+
/**
66+
* Now even when `dbProvider` is applied multiple times, it still only connects to the database once.
67+
*/
6268
const router = os
63-
.use(dbProvider)
69+
.use(dbProvider) // [!code highlight]
6470
.use(({ next }) => {
6571
// Additional middleware logic
6672
return next()

playgrounds/contract-first/src/middlewares/db.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,12 @@ export interface DB {
1818
export const dbProviderMiddleware = os
1919
.$context<{ db?: DB }>()
2020
.middleware(async ({ context, next }) => {
21-
if (context.db) {
22-
return next({
23-
context: {
24-
db: context.db,
25-
},
26-
})
27-
}
28-
29-
const db: DB = createFakeDB()
21+
/**
22+
* Why we should ?? here?
23+
* Because it can avoid `createFakeDB` being called when unnecessary.
24+
* {@link https://orpc.unnoq.com/docs/best-practices/dedupe-middleware}
25+
*/
26+
const db: DB = context.db ?? createFakeDB()
3027

3128
return next({
3229
context: {
Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,35 @@
11
import type { User } from '@/schemas/user'
22
import { os } from '@orpc/server'
33

4-
/**
5-
* Best practices for dedupe-middlewares
6-
* {@link https://orpc.unnoq.com/docs/best-practices/dedupe-middleware}
7-
*/
84
export const requiredAuthMiddleware = os
9-
.$context<{ user?: User }>()
10-
.middleware(({ context, next }) => {
11-
if (context.user) {
12-
return next({
13-
context: { user: context.user },
14-
})
15-
}
16-
5+
.$context<{ session?: { user?: User } }>()
6+
.middleware(async ({ context, next }) => {
177
/**
18-
* You can use headers or cookies here to create the user object:
19-
* import { cookies, headers } from 'next/headers'
20-
* const headerList = await headers();
21-
* const cookieList = await cookies();
22-
*
23-
* These lines are commented out because Stackblitz has issues with Next.js headers and cookies.
24-
* However, this works fine in a local environment.
8+
* Why we should ?? here?
9+
* Because it can avoid `getSession` being called when unnecessary.
10+
* {@link https://orpc.unnoq.com/docs/best-practices/dedupe-middleware}
2511
*/
12+
const session = context.session ?? await getSession()
2613

27-
const user: User = { id: 'unique', name: 'unnoq', email: '[email protected]' }
14+
if (!session.user) {
15+
throw new Error('UNAUTHORIZED')
16+
}
2817

2918
return next({
30-
context: { user },
19+
context: { user: session.user },
3120
})
3221
})
22+
23+
async function getSession() {
24+
/**
25+
* You can use headers or cookies here to create the user object:
26+
* import { cookies, headers } from 'next/headers'
27+
* const headerList = await headers();
28+
* const cookieList = await cookies();
29+
*
30+
* These lines are commented out because Stackblitz has issues with Next.js headers and cookies.
31+
* However, this works fine in a local environment.
32+
*/
33+
34+
return { user: { id: 'unique', name: 'unnoq', email: '[email protected]' } }
35+
}

playgrounds/nextjs/src/middlewares/db.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,15 @@ export interface DB {
1111
}
1212
}
1313

14-
/**
15-
* Best practices for dedupe-middlewares
16-
* {@link https://orpc.unnoq.com/docs/best-practices/dedupe-middleware}
17-
*/
1814
export const dbProviderMiddleware = os
1915
.$context<{ db?: DB }>()
2016
.middleware(async ({ context, next }) => {
21-
if (context.db) {
22-
return next({
23-
context: {
24-
db: context.db,
25-
},
26-
})
27-
}
28-
29-
const db: DB = createFakeDB()
17+
/**
18+
* Why we should ?? here?
19+
* Because it can avoid `createFakeDB` being called when unnecessary.
20+
* {@link https://orpc.unnoq.com/docs/best-practices/dedupe-middleware}
21+
*/
22+
const db: DB = context.db ?? createFakeDB()
3023

3124
return next({
3225
context: {

playgrounds/nuxt/server/middlewares/db.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,15 @@ export interface DB {
1111
}
1212
}
1313

14-
/**
15-
* Best practices for dedupe-middlewares
16-
* {@link https://orpc.unnoq.com/docs/best-practices/dedupe-middleware}
17-
*/
1814
export const dbProviderMiddleware = os
1915
.$context<{ db?: DB }>()
2016
.middleware(async ({ context, next }) => {
21-
if (context.db) {
22-
return next({
23-
context: {
24-
db: context.db,
25-
},
26-
})
27-
}
28-
29-
const db: DB = createFakeDB()
17+
/**
18+
* Why we should ?? here?
19+
* Because it can avoid `createFakeDB` being called when unnecessary.
20+
* {@link https://orpc.unnoq.com/docs/best-practices/dedupe-middleware}
21+
*/
22+
const db: DB = context.db ?? createFakeDB()
3023

3124
return next({
3225
context: {

playgrounds/solid-start/src/middlewares/db.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,15 @@ export interface DB {
1111
}
1212
}
1313

14-
/**
15-
* Best practices for dedupe-middlewares
16-
* {@link https://orpc.unnoq.com/docs/best-practices/dedupe-middleware}
17-
*/
1814
export const dbProviderMiddleware = os
1915
.$context<{ db?: DB }>()
2016
.middleware(async ({ context, next }) => {
21-
if (context.db) {
22-
return next({
23-
context: {
24-
db: context.db,
25-
},
26-
})
27-
}
28-
29-
const db: DB = createFakeDB()
17+
/**
18+
* Why we should ?? here?
19+
* Because it can avoid `createFakeDB` being called when unnecessary.
20+
* {@link https://orpc.unnoq.com/docs/best-practices/dedupe-middleware}
21+
*/
22+
const db: DB = context.db ?? createFakeDB()
3023

3124
return next({
3225
context: {

playgrounds/svelte-kit/src/middlewares/db.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,15 @@ export interface DB {
1111
}
1212
}
1313

14-
/**
15-
* Best practices for dedupe-middlewares
16-
* {@link https://orpc.unnoq.com/docs/best-practices/dedupe-middleware}
17-
*/
1814
export const dbProviderMiddleware = os
1915
.$context<{ db?: DB }>()
2016
.middleware(async ({ context, next }) => {
21-
if (context.db) {
22-
return next({
23-
context: {
24-
db: context.db,
25-
},
26-
})
27-
}
28-
29-
const db: DB = createFakeDB()
17+
/**
18+
* Why we should ?? here?
19+
* Because it can avoid `createFakeDB` being called when unnecessary.
20+
* {@link https://orpc.unnoq.com/docs/best-practices/dedupe-middleware}
21+
*/
22+
const db: DB = context.db ?? createFakeDB()
3023

3124
return next({
3225
context: {

0 commit comments

Comments
 (0)