Saltar al contenido
Meeko
Escribe para buscar en las guías y en la referencia de la API. Ábrela desde cualquier página con / o Ctrl K; muévete con las flechas y entra con Intro.
Empezar

Contenidos

En esta página

ApiRouteDefinition

interfaz

Contrato de un endpoint de server/api/<ruta>.<método>.ts: schemas de entrada y respuesta, autenticación, autorización y handler. Se declara con defineApiRoute.

ts
import type { ApiRouteDefinition } from "@meekojs/meeko/server";

Código fuente src/server/api/contracts.ts:96

Declaración #

ts
interface ApiRouteDefinition<P extends Schema | undefined, Q extends Schema | undefined, B extends Schema | undefined, R extends Schema | undefined, S = unknown, L = undefined, T extends ApiSuccessStatus = ApiSuccessStatus> {
	params?: P
	query?: Q
	body?: B
	response?: R
	status?: T
	auth?: 'required' | 'optional'
	origin?: 'required' | 'none'
	rateLimit?: RateLimitOptions<S>
	contentType?: 'json' | 'response'
	form?: true | ApiFormOptions<ApiFormResult<R, T>, S>
	authorize?: (context: RequestContext<S>) => boolean | Promise<boolean>
	locals?: (context: RequestContext<S>) => L | Promise<L>
	handler: (args: { params: OptionalOutput<P>; query: OptionalOutput<Q>; body: OptionalOutput<B>; context: RequestContext<S>; locals: L }) => Promise<ApiHandlerResult<R, T>> | ApiHandlerResult<R, T>
}

Parámetros de tipo #

P extends Schema | undefined

Schema de params.

Q extends Schema | undefined

Schema de query.

B extends Schema | undefined

Schema de body.

R extends Schema | undefined

Schema de la respuesta.

S = unknown

Tipo de los servicios.

L = undefined

Valor de locals que recibe el handler; undefined sin locals.

T extends ApiSuccessStatus = ApiSuccessStatus

Estado de éxito declarado con status (desde 1.2).

Ejemplo #

ts
import type { ApiRouteDefinition, Schema } from "@meekojs/meeko/server";

type Health = ApiRouteDefinition<undefined, undefined, undefined, Schema<{ ok: boolean }>>;

Propiedades #

params #

propiedad opcional

params?: P

Segmentos dinámicos de la ruta, como cadenas obligatorias.

query #

propiedad opcional

query?: Q

Query string; sus campos aceptan cadenas o listas de cadenas.

body #

propiedad opcional

body?: B

Cuerpo JSON (application/json, hasta 1 MiB) y, con form (desde 1.7), el de un formulario nativo.

response #

propiedad opcional

response?: R

Schema de la respuesta; obligatorio salvo con contentType: "response" o status: 204.

status #

propiedad opcional

status?: T

Estado HTTP de la respuesta correcta (desde 1.2): 200 por defecto, 201 al crear, 202 al aceptar trabajo diferido o 204 sin cuerpo. Con 200, 201 y 202 la respuesta sigue siendo JSON validado con response; con 204 el handler no devuelve nada y no se declara response. No se combina con contentType: "response". Debe ser un literal para que el generador lo lea.

auth #

propiedad opcional

auth?: 'required' | 'optional'

"required" responde 401 UNAUTHENTICATED sin sesión.

origin #

propiedad opcional

origin?: 'required' | 'none'

Comprobación de Origin en las peticiones POST, PUT, PATCH y DELETE. Desde 1.8, por defecto (sin origin) responden 403 INVALID_ORIGIN si su Origin falta, es null o no es el de la aplicación ni uno de SessionManager.allowedOrigins, haya o no sesión. "required" (desde 1.2) equivale al valor por defecto y lo deja explícito.

"none" (desde 1.2, inseguro) desactiva la comprobación en las peticiones sin sesión, también en un formulario nativo (form), para webhooks (incluidos los que envían application/x-www-form-urlencoded), APIs públicas y clientes que no envían Origin, y permite que session.create() cree una sesión sin un Origin permitido. Expone la ruta al CSRF y al login CSRF: úsela sólo con otra prueba de que la petición no viene de otra web, como una firma o un token. Una petición con sesión sigue exigiendo Origin y el token CSRF.

rateLimit #

propiedad opcional

rateLimit?: RateLimitOptions<S>

Límite de peticiones (desde 1.2), como { limit: 5, window: "5m" }: por encima responde 429 RATE_LIMITED con Retry-After, tras Origin y CSRF y antes de auth, authorize, la entrada y el handler. Cuenta en el store de sesiones (Redis entre instancias) y, si el store falla, la petición se rechaza.

contentType #

propiedad opcional

contentType?: 'json' | 'response'

"response" deja que el handler devuelva su propio Response.

form #

propiedad opcional

form?: true | ApiFormOptions<ApiFormResult<R, T>, S>

Acepta también formularios HTML nativos (desde 1.7): application/x-www-form-urlencoded y multipart/form-data, validados con el mismo schema de body. Un envío correcto responde 303 See Other a redirect, al campo return o a la página de Referer; un error vuelve a esa página con 303 y su estado, que useForm({ action }) pinta en el SSR. Exige siempre un Origin permitido. Sin form, esos tipos responden 415 UNSUPPORTED_MEDIA_TYPE.

authorize #

propiedad opcional

authorize?: (context: RequestContext<S>) => boolean | Promise<boolean>

Devolver false responde 403 FORBIDDEN.

locals #

propiedad opcional

locals?: (context: RequestContext<S>) => L | Promise<L>

Calcula un valor por petición que el handler recibe como locals (desde 1.2), como el usuario actual. Se ejecuta tras Origin, CSRF, auth, authorize y la validación de la entrada, y justo antes del handler; un ApiError que lance (por ejemplo 401 o 403) es la respuesta. Declárelo antes de handler para que TypeScript infiera su tipo.

handler #

propiedad

handler: (args: { params: OptionalOutput<P>; query: OptionalOutput<Q>; body: OptionalOutput<B>; context: RequestContext<S>; locals: L }) => Promise<ApiHandlerResult<R, T>> | ApiHandlerResult<R, T>

Recibe la entrada validada, el contexto y locals; su resultado se valida con response. Con status: 204 no devuelve nada.

Véase también #

¿Te sirvió esta página?

Añadir un comentario

Se envía al elegir «Sí» o «No». Solo se guardan la página, tu respuesta y el comentario: ni cookies ni datos tuyos.

0 de 2000 caracteres

Editar en GitHub: packages/meeko/src/server/api/contracts.ts