Proxy Layer

Back

Loading concept...

🚪 The Proxy Layer: Your App’s Secret Doorman

Imagine your Next.js app is a fancy hotel. Guests (requests) arrive at the front door, but before they enter, there’s a doorman who decides:

  • Where should this guest go?
  • Should we send them somewhere else?
  • Can we change their outfit before they enter?
  • Can we wrap their luggage differently when they leave?

That doorman is the Proxy Layer! Let’s meet this helpful friend.


🎯 What is a Proxy?

Think of a proxy like a translator between you and a friend who speaks a different language.

You → Proxy → Friend
     (translator)

In Next.js, the proxy sits between your app and external services (like APIs). It catches requests, modifies them if needed, and sends them on their way.

Real Life Example:

  • You want pizza from an Italian restaurant
  • The proxy takes your order
  • It translates “pizza” to “pizza margherita, per favore”
  • Sends it to the restaurant
  • Returns with your food!

📄 The proxy.ts File

This is where our doorman lives! It’s a special file in your Next.js project.

Where Does It Live?

your-project/
├── src/
│   ├── app/
│   └── proxy.ts  ← Here!

Basic Structure

// proxy.ts
export default function proxy(request) {
  // Decide what to do
  // with each request
  return response;
}

Simple Analogy: The proxy.ts file is like a recipe book for your doorman. It tells him exactly what to do when different types of guests arrive.


🔍 Proxy Matching

How does our doorman know which guests to help? Matching!

Pattern Matching

Think of it like a game of “Does this match?”

// Match all API requests
if (request.url.startsWith('/api/')) {
  // Handle API requests
}

// Match specific paths
if (request.url === '/users') {
  // Handle users endpoint
}

Wildcards

Sometimes we need to match many things at once:

// Match /api/users, /api/posts, etc.
'/api/*'

// Match /v1/users/123/profile
'/v1/users/*/profile'

Like Playing Cards:

  • * is like a wild card - it matches anything!
  • /api/* matches /api/cats, /api/dogs, /api/unicorns

↩️ Redirects in Proxy

Sometimes our doorman says: “Wrong door! Go over there!”

What is a Redirect?

A redirect tells the browser: “This page moved. Go to this new address instead.”

// Old URL → New URL
if (request.url === '/old-page') {
  return redirect('/new-page');
}

Types of Redirects

Code Meaning Like…
301 Moved forever “We moved house permanently!”
302 Moved temporarily “We’re visiting grandma’s house”
307 Same method “Go there, but knock the same way”

Example

export function handleRedirect(request) {
  const url = request.url;

  // Permanent redirect
  if (url === '/blog-old') {
    return Response.redirect(
      '/blog',
      301
    );
  }
}

The Browser’s POV:

  1. User clicks /blog-old
  2. Proxy says “Go to /blog instead!”
  3. Browser updates the address bar
  4. User sees the new page

🔄 Rewrites in Proxy

This is the sneaky trick! Unlike redirects, rewrites happen secretly.

Redirect vs Rewrite

REDIRECT: User sees new URL
REWRITE:  User sees OLD URL, gets NEW content

Think of it like:

  • Redirect: “Go to the other restaurant”
  • Rewrite: “Stay here, we’ll secretly get food from the other restaurant”

Why Use Rewrites?

  • Hide ugly API URLs
  • Keep URLs clean for users
  • Connect to external services secretly

Example

export function handleRewrite(request) {
  // User visits /products
  // But actually gets data from
  // external API

  if (request.url === '/products') {
    return fetch(
      'https://api.store.com/items'
    );
  }
}

The Magic:

  1. User visits yoursite.com/products
  2. Proxy secretly fetches from api.store.com/items
  3. User still sees yoursite.com/products
  4. Content comes from external API!

✏️ Request Modification

Before sending a request forward, we can change it!

What Can We Modify?

graph TD A["Original Request"] --> B["Proxy"] B --> C["Add Headers"] B --> D["Change URL"] B --> E["Add Auth Token"] B --> F["Modify Body"] C --> G["Modified Request"] D --> G E --> G F --> G

Adding Headers

function modifyRequest(request) {
  // Clone and modify
  const newHeaders = new Headers(
    request.headers
  );

  // Add secret key
  newHeaders.set(
    'X-API-Key',
    'secret123'
  );

  return new Request(request.url, {
    headers: newHeaders
  });
}

Adding Authentication

function addAuth(request) {
  const headers = new Headers(
    request.headers
  );

  // Add bearer token
  headers.set(
    'Authorization',
    'Bearer ' + getToken()
  );

  return new Request(request.url, {
    method: request.method,
    headers: headers,
    body: request.body
  });
}

Why Modify Requests?

  • Add API keys (so users don’t see them!)
  • Add user authentication
  • Transform data format
  • Add tracking information

📤 Response Modification

The doorman can also wrap gifts differently before handing them back!

What Can We Change?

graph TD A["Original Response"] --> B["Proxy"] B --> C["Change Headers"] B --> D["Transform Body"] B --> E["Add CORS"] B --> F["Cache Control"] C --> G["Modified Response"] D --> G E --> G F --> G

Modifying Headers

async function modifyResponse(
  request
) {
  // Get original response
  const response = await fetch(
    request
  );

  // Create new headers
  const headers = new Headers(
    response.headers
  );

  // Add CORS header
  headers.set(
    'Access-Control-Allow-Origin',
    '*'
  );

  return new Response(
    response.body,
    { headers }
  );
}

Transforming Response Body

async function transformBody(
  request
) {
  const response = await fetch(
    request
  );
  const data = await response.json();

  // Add extra info
  const enhanced = {
    ...data,
    timestamp: Date.now(),
    source: 'proxy'
  };

  return new Response(
    JSON.stringify(enhanced),
    {
      headers: {
        'Content-Type':
          'application/json'
      }
    }
  );
}

Real Examples:

  • Add caching headers
  • Remove sensitive data before sending
  • Add CORS headers for cross-origin requests
  • Compress response data

🎨 Complete Proxy Example

Let’s put it all together!

// proxy.ts

export default async function proxy(
  request: Request
) {
  const url = new URL(request.url);

  // 1. REDIRECT old paths
  if (url.pathname === '/old') {
    return Response.redirect(
      '/new',
      301
    );
  }

  // 2. REWRITE API calls
  if (url.pathname.startsWith('/api/')) {
    const apiUrl =
      'https://backend.com' +
      url.pathname;

    // 3. MODIFY REQUEST
    const newReq = new Request(apiUrl, {
      method: request.method,
      headers: {
        ...request.headers,
        'X-API-Key': 'secret'
      },
      body: request.body
    });

    // 4. Get response
    const res = await fetch(newReq);

    // 5. MODIFY RESPONSE
    const headers = new Headers(
      res.headers
    );
    headers.set(
      'X-Powered-By',
      'My Proxy'
    );

    return new Response(res.body, {
      status: res.status,
      headers
    });
  }

  // Default: pass through
  return fetch(request);
}

🌟 Quick Summary

Concept What It Does Analogy
Proxy Middleman for requests Translator
proxy.ts Configuration file Doorman’s rulebook
Matching Find which requests to handle ID checking
Redirect Send to new URL (visible) “Go next door”
Rewrite Secretly fetch from elsewhere Secret food delivery
Request Mod Change outgoing request Add secret note
Response Mod Change incoming response Rewrap the gift

💡 Remember This!

The Proxy Layer is your app’s helpful doorman.

It decides where requests go, can secretly fetch from other places, and can dress up both requests and responses before they reach their destination.

You now understand the Proxy Layer! 🎉

Next time you need to:

  • Hide API keys → Use Request Modification
  • Clean up URLs → Use Rewrites
  • Move old pages → Use Redirects
  • Add headers → Use Response Modification

Your doorman has got your back! 🚀

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.