Guide
Endpoints & routing
The method name is the route. No route table, no controller to keep in sync.
@Route
import {
Route, CloudFunction, catchError, setupSwagger,
} from 'parse-server-kit';
@Route(Product) // -> /api/products/*
@Route('menu-items') // -> /api/menu-items/*
The prefix is the kebab-case plural of the JavaScript class name. Each method becomes /{prefix}/{methodName}, matched against the class's real method list — so there is no string parsing and no collision between getProduct and getProductCategory.
createProduct -> POST /api/products/createProduct
listProducts -> GET /api/products/listProducts
Rename the method and the route follows. Both static and prototype method names are captured.
@CloudFunction
@CloudFunction({
methods: ['POST'],
description: 'Create a product',
validation: { requireUser: true, fields: { name: { required: true } } },
requireRoles: ['Admin'],
rateLimit: { windowMs: 60000, max: 30 },
swagger: { tags: ['Products'] },
})
static async createProduct(req: Parse.Cloud.FunctionRequest) { … }
| Option | Effect |
|---|---|
methods | Allowed HTTP verbs. A mismatch answers 405 |
requiresAuth | Refuses a caller with no session before your body runs. The master key passes — the system is not an anonymous caller |
validation | Parse's own validator — requireUser, fields, and so on |
requireRoles | Checked before your body runs |
requireAllRoles | true demands every listed role; default is any |
roleCacheMs | Per-endpoint override of the role cache; 0 never caches |
rateLimit | Per-function limit, enforced on the entity route and on a direct /functions/{name} call. Per process — N instances means N times the limit |
customErrorMessage | Replaces the default refusal text |
swagger | summary, description, tags, responses |
@ProtectedCloudFunction is the same decorator with methods: ['POST'] and requireUser already applied.
{type: String} and convert:
Number(req.params.limit), req.params.active === 'true'.
Error handling
const [err, saved] = await catchError(product.save(null, { sessionToken }));
if (err) throw err;
catchError is the convention throughout the library: it turns a rejected promise into a tuple rather than a try/catch around every await.
OpenAPI
Every endpoint appears in the generated document with its real route, derived from @Route — no annotations needed. GET and HEAD emit query parameters; everything else emits a JSON requestBody, because a browser cannot send a body on a GET. Security schemes are derived from requireUser, requireMaster and requireRoles.
setupSwagger(app, { title: 'My API', version: '1.0.0' });
// UI at /api-docs, document always at /api-docs/json
Without swagger-ui-express installed the browser page is skipped with a warning; the document still serves.