Integrar Hono en Next.js.
Instalamos la dependencia de Hono con npm:
npm install hono
Agregamos una ruta del tipo catch-all para la API creando el archivo app/api/[[...route]]/route.ts
.
Dentro del archivo route.ts
inicializamos Hono y especificamos las constantes GET
y POST
para que Next.js maneje las rutas API pero a través de Hono.
import { Hono } from 'hono'import { handle } from 'hono/vercel' export const runtime = 'edge' const app = new Hono().basePath('/api') app.get('/hello', (c) => { return c.json({ message: 'Hello Next.js!', })}) export const GET = handle(app)export const POST = handle(app)
Ahora podemos ir al endpoint http://localhost:3000/api/hello
para verificar que la integración esté correcta.
También podemos utilizar Zod para validar parámetros o cualquier otra entrada en Hono.
Instalamos Zod y Zod Validator para Hono:
npm install zodnpm install @hono/zod-validator
Ahora, para probar Zod, añadimos otro endpoint /hello/:test
y utilizamos el middleware de zValidator
y especificamos el tipo de parámetro que será test
, por ejemplo string()
.
+import { zValidator } from '@hono/zod-validator' import { Hono } from 'hono' import { handle } from 'hono/vercel'+import { z } from 'zod' export const runtime = 'edge' const app = new Hono().basePath('/api') app .get('/hello', (c) => { return c.json({ message: '¡Hola Next.js!', }) })+ .get( + '/hello/:test',+ zValidator(+ 'param',+ z.object({+ test: z.string(),+ })+ ),+ (c) => {+ const { test } = c.req.valid('param')+ + return c.json({+ message: `¡Hola Next.js!`,+ test: test,+ })+ }+ ) export const GET = handle(app) export const POST = handle(app)
Para proteger nuestros endpoints de la API con Clerk, podemos hacerlo mediante un middleware.
Instalamos Clerk para Hono y el backend:
npm install @hono/clerk-auth @clerk/backend
Ahora, en nuestro route.ts
para las APIs, agregamos el middleware de clerkMiddleware
para validar que el usuario esté autorizado para utilizar nuestra API.
+import { clerkMiddleware, getAuth } from '@hono/clerk-auth' import { Hono } from 'hono' import { handle } from 'hono/vercel' export const runtime = 'edge' const app = new Hono().basePath('/api') app .get('/hello', clerkMiddleware(), (c) => { const auth = getAuth(c) if (!auth?.userId) { return c.json({ message: 'Unauthorized', }, 401) } return c.json({ message: '¡Hola Next.js!', userId: auth.userId, }) }) export const GET = handle(app) export const POST = handle(app)
Si visitamos el endpoint http://localhost:3000/api/hello
y no hemos iniciado sesión, obtendremos un error 401
.
Y si iniciamos sesión, obtenemos nuestro mensaje de bienvenida y el id del usuario.