Skip to content

StevanusAndika/next-api

Repository files navigation

Next.js API Management & CORS Learning Project

πŸ“š Project Overview

This project is designed as a learning resource for understanding API management, CORS configuration, and full-stack development using Next.js 16, TypeScript, Prisma ORM, and MySQL.

🎯 Learning Objectives

  • βœ… API Route Management in Next.js App Router
  • βœ… CORS Configuration and security best practices
  • βœ… CRUD Operations with proper RESTful conventions
  • βœ… TypeScript Integration for type-safe APIs
  • βœ… Database Management with Prisma ORM
  • βœ… Frontend-Backend Integration with React/TypeScript
  • βœ… Error Handling and validation
  • βœ… API Testing with Postman

πŸ—οΈ Project Structure

next-api/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ api/
β”‚   β”‚   └── posts/
β”‚   β”‚       β”œβ”€β”€ route.ts          # GET ALL, POST
β”‚   β”‚       └── [id]/
β”‚   β”‚           └── route.ts      # GET, PUT, DELETE by ID
β”‚   β”œβ”€β”€ layout.tsx
β”‚   β”œβ”€β”€ page.tsx                  # Frontend React UI
β”‚   └── globals.css
β”œβ”€β”€ types/
β”‚   β”œβ”€β”€ post.ts                   # TypeScript interfaces
β”‚   └── api.ts                    # API-specific types
β”œβ”€β”€ prisma/
β”‚   β”œβ”€β”€ schema.prisma             # Database schema
β”‚   └── client/                   # Prisma client
β”œβ”€β”€ middleware.ts                 # Global CORS configuration
└── package.json

πŸš€ Features

Backend API

  • RESTful API with proper HTTP methods
  • CORS enabled for cross-origin requests
  • TypeScript for type safety
  • Prisma ORM for database operations
  • MySQL database integration
  • Error handling with appropriate status codes

Frontend

  • React with TypeScript for type-safe UI
  • CRUD operations integration
  • Real-time updates after mutations
  • Form validation and error handling
  • Responsive design

πŸ› οΈ Installation & Setup

Prerequisites

  • Node.js 18+
  • MySQL database
  • Postman (for API testing)

1. Clone and Install Dependencies

git clone <your-repo>
cd next-api
npm install

2. Database Setup

# Configure your database in .env
DATABASE_URL="mysql://username:password@localhost:3306/database_name"

# Generate Prisma client
npx prisma generate

# Push schema to database
npx prisma db push

# Or run migrations
npx prisma migrate dev --name init

3. Run Development Server

npm run dev

πŸ“‘ API Endpoints

Posts CRUD API

Method Endpoint Description Body
GET /api/posts Get all posts -
POST /api/posts Create new post {title, content, published}
GET /api/posts/[id] Get post by ID -
PUT /api/posts/[id] Update post by ID {title, content, published}
DELETE /api/posts/[id] Delete post by ID -
OPTIONS /api/posts/* CORS preflight -

Example API Requests

Create Post:

curl -X POST http://localhost:3000/api/posts \
  -H "Content-Type: application/json" \
  -d '{"title":"My Post","content":"Post content","published":true}'

Get All Posts:

curl -X GET http://localhost:3000/api/posts

πŸ”§ CORS Configuration

Understanding CORS (Cross-Origin Resource Sharing)

CORS is a security feature that controls how web applications from one domain can interact with resources from another domain.

Implementation Methods

1. Per-Route CORS (Implemented in this project)

// In each route.ts file
const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type, Authorization',
};

export async function OPTIONS() {
  return NextResponse.json({}, { headers: corsHeaders });
}

2. Global Middleware CORS

// middleware.ts
export function middleware(request) {
  const response = NextResponse.next();
  
  response.headers.set('Access-Control-Allow-Origin', '*');
  response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  
  return response;
}

3. Environment-Specific CORS

const allowedOrigins = [
  'http://localhost:3000',
  'https://yourdomain.com'
];

const getCorsHeaders = (request: Request) => {
  const origin = request.headers.get('origin');
  const isAllowed = allowedOrigins.includes(origin || '');
  
  return {
    'Access-Control-Allow-Origin': isAllowed ? origin : '*',
    'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
    'Access-Control-Allow-Headers': 'Content-Type, Authorization',
  };
};

πŸ§ͺ Testing the API

Using Postman

  1. Import the Postman Collection

    • Use the provided Posts-CRUD-API.postman_collection.json
    • Set environment variables: base_url and content_type
  2. Test All Endpoints

    • Follow the "Test All Scenarios" collection for complete flow
    • Test error cases (validation, not found, etc.)

Manual Testing with curl

# Test CORS preflight
curl -X OPTIONS http://localhost:3000/api/posts \
  -H "Origin: http://localhost:3000" \
  -H "Access-Control-Request-Method: POST" \
  -I

# Test API endpoints
curl -X GET http://localhost:3000/api/posts
curl -X POST http://localhost:3000/api/posts \
  -H "Content-Type: application/json" \
  -d '{"title":"Test","content":"Test content"}'

πŸ“Š Database Schema

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  published Boolean  @default(false)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

🎨 Frontend Features

  • Real-time CRUD operations
  • Type-safe forms with React Hook Form
  • Error handling and loading states
  • Responsive UI design
  • Inline editing capabilities

πŸ” Common CORS Issues & Solutions

Issue: CORS Blocked by Browser

Solution: Ensure OPTIONS method is handled and proper headers are set

Issue: Preflight Request Failing

Solution: Implement OPTIONS handler with correct CORS headers

Issue: Specific Origins Not Working

Solution: Use origin validation in CORS headers

Issue: Credentials Not Working

Solution: Add Access-Control-Allow-Credentials: true header

πŸš€ Deployment Considerations

Environment Variables

# Development
DATABASE_URL="mysql://user:pass@localhost:3306/dev_db"

# Production  
DATABASE_URL="mysql://user:pass@production-host:3306/prod_db"

CORS for Production

// Restrict to your domain in production
const allowedOrigins = process.env.NODE_ENV === 'production' 
  ? ['https://yourdomain.com']
  : ['http://localhost:3000', 'http://localhost:3001'];

πŸ“ Learning Checklist

  • Understand API route structure in Next.js
  • Implement CRUD operations with proper HTTP methods
  • Configure CORS for cross-origin requests
  • Handle preflight OPTIONS requests
  • Implement proper error handling and status codes
  • Test API endpoints with Postman
  • Integrate frontend with backend API
  • Understand TypeScript benefits in API development
  • Implement database operations with Prisma
  • Deploy and configure for production

πŸ› οΈ Development Scripts

npm run dev          # Start development server
npm run build        # Build for production
npm run start        # Start production server
npx prisma generate  # Generate Prisma client
npx prisma db push   # Push schema to database
npx prisma studio    # Open Prisma database GUI

🀝 Contributing

This is a learning project! Feel free to:

  • Add new features
  • Improve error handling
  • Enhance the UI/UX
  • Add authentication
  • Implement pagination
  • Add API documentation with Swagger

πŸ“š Additional Resources

🎯 Next Steps for Learning

  1. Add Authentication - JWT or NextAuth.js
  2. Implement Pagination - Limit/offset or cursor-based
  3. Add API Rate Limiting - Prevent abuse
  4. Implement Caching - Redis for performance
  5. Add API Documentation - Swagger/OpenAPI
  6. Write Tests - Jest for API testing
  7. Containerize - Docker for deployment
  8. Add Monitoring - Logging and metrics

Happy Learning! πŸš€

This project demonstrates real-world API development patterns that you'll encounter in professional web development.