Skip to main content
📞 1-888-784-3881🚀 Start Project
🔧Examples

API Boilerplate

REST API boilerplate with auth, validation, and tests.

⏱️ 12 min read

Structure

api/

├── src/

│ ├── routes/

│ │ ├── leads.ts

│ │ ├── properties.ts

│ │ └── offers.ts

│ ├── middleware/

│ │ ├── auth.ts

│ │ ├── validate.ts

│ │ └── rateLimit.ts

│ ├── lib/

│ │ ├── proptech.ts

│ │ └── db.ts

│ └── index.ts

├── tests/

│ └── leads.test.ts

└── package.json

Auth Middleware

// src/middleware/auth.ts

import { NextRequest, NextResponse } from 'next/server';

export async function authMiddleware(request: NextRequest) {

const apiKey = request.headers.get('x-api-key');

if (!apiKey) {

return NextResponse.json(

{ error: 'API key required' },

{ status: 401 }

);

}

// Validate API key

const isValid = await validateApiKey(apiKey);

if (!isValid) {

return NextResponse.json(

{ error: 'Invalid API key' },

{ status: 401 }

);

}

return NextResponse.next();

}

Validation Middleware

// src/middleware/validate.ts

import { z } from 'zod';

import { NextRequest, NextResponse } from 'next/server';

export function validate<T>(schema: z.Schema<T>) {

return async (request: NextRequest) => {

try {

const body = await request.json();

const data = schema.parse(body);

return { data };

} catch (error) {

if (error instanceof z.ZodError) {

return {

error: NextResponse.json(

{ error: 'Validation failed', details: error.errors },

{ status: 400 }

),

};

}

throw error;

}

};

}

Test Example

// tests/leads.test.ts

import { describe, it, expect } from 'vitest';

describe('Leads API', () => {

it('creates a lead', async () => {

const res = await fetch('/api/leads', {

method: 'POST',

headers: {

'Content-Type': 'application/json',

'x-api-key': 'test_key',

},

body: JSON.stringify({

name: 'Test User',

email: 'test@example.com',

phone: '555-1234',

}),

});

expect(res.status).toBe(201);

const data = await res.json();

expect(data.id).toBeDefined();

});

it('validates required fields', async () => {

const res = await fetch('/api/leads', {

method: 'POST',

headers: {

'Content-Type': 'application/json',

'x-api-key': 'test_key',

},

body: JSON.stringify({}),

});

expect(res.status).toBe(400);

});

});