Get a working API server up and running with I/O validation in just a few minutes.
Make sure your tsconfig.json has strict mode enabled:
{
"compilerOptions": {
"strict": true,
"skipLibCheck": true
}
}
Step 2: Create Configuration
Create a configuration file for your server:
import { createConfig } from "express-zod-api";
const config = createConfig({
http: { listen: 8090 },
cors: true,
});
export default config;
Port number for the HTTP server
Enable cross-origin resource sharing
Step 3: Create Your First Endpoint
Create an endpoint that responds with a greeting:
import { defaultEndpointsFactory } from "express-zod-api";
import { z } from "zod";
export const helloEndpoint = defaultEndpointsFactory.build({
method: "get",
input: z.object({
name: z.string().optional(),
}),
output: z.object({
greetings: z.string(),
}),
handler: async ({ input: { name }, logger }) => {
logger.debug(`Greeting ${name || "World"}`);
return { greetings: `Hello, ${name || "World"}. Happy coding!` };
},
});
What’s Happening Here?
Input Schema
The input defines what data the endpoint accepts. Here, an optional name string from the query parameters.
Output Schema
The output defines what data the endpoint returns. The response is validated against this schema.
Handler Function
The async handler receives validated input and returns validated output. TypeScript knows the exact types!
Step 4: Set Up Routing
Connect your endpoint to a URL path:
import { Routing } from "express-zod-api";
import { helloEndpoint } from "./endpoints";
const routing: Routing = {
v1: {
hello: helloEndpoint,
},
};
export default routing;
This creates the route GET /v1/hello.
Step 5: Start the Server
Create your server entry point:
import { createServer } from "express-zod-api";
import config from "./config";
import routing from "./routing";
createServer(config, routing);
Step 6: Test Your API
Start your server:
tsx index.ts
# or: node --loader tsx index.ts
# or: ts-node index.ts
Test with curl:
curl "http://localhost:8090/v1/hello?name=Rick"
You should see:
{
"status": "success",
"data": {
"greetings": "Hello, Rick. Happy coding!"
}
}
Complete Example
Here’s everything in one file:
import { createServer, createConfig, defaultEndpointsFactory, Routing } from "express-zod-api";
import { z } from "zod";
// Configuration
const config = createConfig({
http: { listen: 8090 },
cors: true,
});
// Endpoint
const helloEndpoint = defaultEndpointsFactory.build({
method: "get",
input: z.object({
name: z.string().optional(),
}),
output: z.object({
greetings: z.string(),
}),
handler: async ({ input: { name } }) => ({
greetings: `Hello, ${name || "World"}. Happy coding!`,
}),
});
// Routing
const routing: Routing = {
v1: {
hello: helloEndpoint,
},
};
// Start server
createServer(config, routing);
What’s Next?
Common Next Steps
Add a POST Endpoint
const createUserEndpoint = defaultEndpointsFactory.build({
method: "post",
input: z.object({
name: z.string().min(1),
email: z.string().email(),
}),
output: z.object({
id: z.string(),
name: z.string(),
email: z.string(),
}),
handler: async ({ input }) => {
// Save to database
const user = await db.users.create(input);
return user;
},
});
Add Path Parameters
const routing: Routing = {
v1: {
users: {
":id": getUserEndpoint, // GET /v1/users/:id
},
},
};
const getUserEndpoint = defaultEndpointsFactory.build({
method: "get",
input: z.object({
id: z.string(), // from path parameter
}),
output: z.object({
id: z.string(),
name: z.string(),
}),
handler: async ({ input: { id } }) => {
return await db.users.findById(id);
},
});
Handle Errors
import createHttpError from "http-errors";
const endpoint = defaultEndpointsFactory.build({
handler: async ({ input }) => {
const user = await db.users.findById(input.id);
if (!user) {
throw createHttpError(404, "User not found");
}
return user;
},
});
Troubleshooting
If port 8090 is already in use, change it in your config:const config = createConfig({
http: { listen: 3000 }, // Use a different port
cors: true,
});
Make sure you have strict: true in your tsconfig.json and all required dependencies installed:pnpm add -D @types/express @types/node @types/http-errors
Enable CORS in your configuration:const config = createConfig({
http: { listen: 8090 },
cors: true, // Enable CORS
});