Shipkit
DocsFeaturesPricing
DocsFeaturesPricing

Shipkit DocumentationBuild memory optimizationDevelopment GuideEnvironment VariablesError HandlingFile StructureMiddlewareRebranding Guide

Vercel Deployment Checks

Development GuideCLIDependency UpdatesDevToolsFeature FlagsAI PromptsSetup RequirementsSupply chaintRPCWeb Workers

FeaturesAIAnalytics IntegrationAuthenticationCMSDatabaseEmailHapticsPaymentsComponent RegistryStorageUIVisual BuilderWaitlist Feature

Quick StartDeploymentEnvironment VariablesFile StructureSetup Wizard

Caching & Rate LimitingContent ManagementError HandlingMarkdown and MDXMiddlewareProxy-Safe Server ActionsRebranding GuideWebhook Security Implementation GuideMulti-Zone ArchitectureVercel Deployment

IntegrationsPayload CMSDataFast Analytics IntegrationGoogle Analytics IntegrationGoogle Tag Manager IntegrationPostHogStatSig IntegrationUmami Analytics IntegrationAuth.js IntegrationBetter AuthClerkStack Auth IntegrationSupabase Authentication IntegrationBuilder.io IntegrationPayload CMS IntegrationAWS S3 IntegrationResend Email IntegrationUpstash Redis IntegrationVercel Blob IntegrationLemon SqueezyPolarStripe

API RoutesComponentsAPI Route SnippetsAuthentication SnippetsComponent SnippetsForm Handling SnippetsSnippets Introduction

    API Route Snippets

    Basic Route Handler

    // src/app/api/posts/route.ts
    import { NextResponse } from "next/server";
    import { ValidationService } from "@/server/services/validation-service";
    import { ErrorService } from "@/server/services/error-service";
    import { z } from "zod";
    
    const createPostSchema = z.object({
      title: z.string().min(1),
      content: z.string().optional(),
    });
    
    export async function POST(req: Request) {
      try {
        const json = await req.json();
        const result = await ValidationService.validate(createPostSchema, json);
    
        if (!result.success) {
          return NextResponse.json({ error: result.error }, { status: 400 });
        }
    
        const post = await db?.post.create({
          data: result.data,
        });
    
        return NextResponse.json(post, { status: 201 });
      } catch (error) {
        const appError = ErrorService.handleError(error);
        return NextResponse.json(
          { error: appError },
          { status: appError.code === "UNAUTHORIZED" ? 401 : 500 }
        );
      }
    }
    

    Protected Route Handler

    // src/app/api/protected/posts/route.ts
    import { auth } from "@/server/auth";
    import { NextResponse } from "next/server";
    import { ValidationService } from "@/server/services/validation-service";
    import { ErrorService } from "@/server/services/error-service";
    import { z } from "zod";
    
    const schema = z.object({
      title: z.string().min(1),
      content: z.string().optional(),
    });
    
    export async function POST(req: Request) {
      try {
        const session = await auth();
        if (!session?.user) {
          return ErrorService.throwUnauthorized("Not authenticated");
        }
    
        const json = await req.json();
        const result = await ValidationService.validate(schema, json);
    
        if (!result.success) {
          return NextResponse.json({ error: result.error }, { status: 400 });
        }
    
        const post = await db?.post.create({
          data: {
            ...result.data,
            authorId: session.user.id,
          },
        });
    
        return NextResponse.json(post, { status: 201 });
      } catch (error) {
        const appError = ErrorService.handleError(error);
        return NextResponse.json(
          { error: appError },
          { status: appError.code === "UNAUTHORIZED" ? 401 : 500 }
        );
      }
    }
    

    File Upload Handler

    // src/app/api/upload/route.ts
    import { auth } from "@/server/auth";
    import { NextResponse } from "next/server";
    import { ErrorService } from "@/server/services/error-service";
    
    export async function POST(req: Request) {
      try {
        const session = await auth();
        if (!session?.user) {
          return ErrorService.throwUnauthorized("Not authenticated");
        }
    
        const formData = await req.formData();
        const file = formData.get("file") as File;
    
        if (!file) {
          return ErrorService.throwBadRequest("No file provided");
        }
    
        // Process file upload
        // Example: Upload to S3, process image, etc.
        const uploadedFile = await uploadToStorage(file);
    
        return NextResponse.json(uploadedFile, { status: 201 });
      } catch (error) {
        const appError = ErrorService.handleError(error);
        return NextResponse.json(
          { error: appError },
          { status: appError.code === "UNAUTHORIZED" ? 401 : 500 }
        );
      }
    }
    
    async function uploadToStorage(file: File) {
      // Implement file upload logic
      return {
        url: "https://example.com/files/image.jpg",
        filename: file.name,
        size: file.size,
        type: file.type,
      };
    }
    

    Dynamic Route Handler

    // src/app/api/posts/[id]/route.ts
    import { auth } from "@/server/auth";
    import { NextResponse } from "next/server";
    import { ErrorService } from "@/server/services/error-service";
    
    interface RouteContext {
      params: { id: string };
    }
    
    export async function GET(req: Request, { params }: RouteContext) {
      try {
        const session = await auth();
        if (!session?.user) {
          return ErrorService.throwUnauthorized("Not authenticated");
        }
    
        const post = await db?.post.findUnique({
          where: { id: params.id },
        });
    
        if (!post) {
          return ErrorService.throwNotFound("Post not found");
        }
    
        return NextResponse.json(post);
      } catch (error) {
        const appError = ErrorService.handleError(error);
        return NextResponse.json(
          { error: appError },
          { status: appError.code === "NOT_FOUND" ? 404 : 500 }
        );
      }
    }
    
    export async function DELETE(req: Request, { params }: RouteContext) {
      try {
        const session = await auth();
        if (!session?.user) {
          return ErrorService.throwUnauthorized("Not authenticated");
        }
    
        const post = await db?.post.findUnique({
          where: { id: params.id },
        });
    
        if (!post) {
          return ErrorService.throwNotFound("Post not found");
        }
    
        if (post.authorId !== session.user.id) {
          return ErrorService.throwForbidden("Not authorized");
        }
    
        await db?.post.delete({
          where: { id: params.id },
        });
    
        return NextResponse.json({ success: true });
      } catch (error) {
        const appError = ErrorService.handleError(error);
        return NextResponse.json(
          { error: appError },
          { status: appError.code === "NOT_FOUND" ? 404 : 500 }
        );
      }
    }