Lithia
Fundamentals

Response

Understanding the Response object in Lithia

The Response object in Lithia provides methods to send data back to the client, including JSON, HTML, files, and various HTTP status codes.

Basic Usage

src/routes/api/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Send JSON response
  res.json({ message: 'Hello World' });
};
src/routes/text/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Send text response using send()
  res.send('Hello World');
};
src/routes/html/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Send HTML response using send()
  res
    .setHeaders({
      'Content-Type': 'text/html',
    })
    .send('<h1>Hello World</h1>');
};

Response Methods

JSON Response

Send JSON data to the client

src/routes/users/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  const data = {
    id: 1,
    name: 'John Doe',
    email: 'john@example.com'
  };
  
  res.json(data);
};

Send Response

Send any data type with automatic content handling

src/routes/status/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Send string
  res.send('Server is running');
  
  // Send number
  res.send(42);
  
  // Send object (automatically becomes JSON)
  res.send({ status: 'ok' });
};

Redirect Response

Redirect the client to another URL

src/routes/redirect/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Permanent redirect (301)
  res.redirect('/new-page', 301);
};
src/routes/temp/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Temporary redirect (302)
  res.redirect('/temporary-page');
};

HTTP Status Code Helpers

Lithia provides convenient methods for common HTTP status codes

src/routes/success/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Success responses using helper methods
  res.ok({ message: 'Success' }); // 200 OK
  res.created({ id: 1, name: 'New Item' }); // 201 Created
  res.noContent(); // 204 No Content
};
src/routes/errors/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Client error responses using helper methods
  res.badRequest({ error: 'Invalid input' }); // 400 Bad Request
  res.unauthorized({ error: 'Authentication required' }); // 401 Unauthorized
  res.forbidden({ error: 'Access denied' }); // 403 Forbidden
  res.notFound({ error: 'Resource not found' }); // 404 Not Found
  res.conflict({ error: 'Resource already exists' }); // 409 Conflict
  res.unprocessableEntity({ error: 'Validation failed' }); // 422 Unprocessable Entity
  res.tooManyRequests({ error: 'Rate limit exceeded' }); // 429 Too Many Requests
};
src/routes/server-error/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Server error responses using helper methods
  res.internalServerError({ error: 'Something went wrong' }); // 500 Internal Server Error
  res.badGateway({ error: 'Upstream server error' }); // 502 Bad Gateway
  res.serviceUnavailable({ error: 'Service temporarily unavailable' }); // 503 Service Unavailable
};

Response Headers

Set custom response headers

src/routes/headers/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Set single header
  res.addHeader('Content-Type', 'application/json');
  res.addHeader('Cache-Control', 'no-cache');
  
  // Set multiple headers
  res.setHeaders({
    'Content-Type': 'application/json',
    'Cache-Control': 'no-cache',
    'X-Custom-Header': 'custom-value'
  });
  
  res.json({ message: 'Response with custom headers' });
};

Cookies

Set response cookies

src/routes/login/route.post.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Set a simple cookie
  res.cookie('theme', 'dark');
  
  // Set cookie with options
  res.cookie('sessionId', 'abc123', {
    httpOnly: true,
    secure: true,
    maxAge: 3600000, // 1 hour
    sameSite: 'strict'
  });
  
  res.json({ message: 'Cookie set' });
};

Error Handling

Handle errors with appropriate responses

src/routes/api/data/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
import { ValidationError, NotFoundError } from '@/errors';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  try {
    const data = await processData();
    res.json(data);
  } catch (error) {
    if (error instanceof ValidationError) {
      res.status(400).json({ 
        error: 'Validation failed',
        details: error.message 
      });
    }
    
    if (error instanceof NotFoundError) {
      res.status(404).json({ 
        error: 'Resource not found' 
      });
    }
    
    // Generic error
    res.status(500).json({ 
      error: 'Internal server error' 
    });
  }
};

Response Templates

Use response templates for consistent formatting

utils/response.ts
import type { LithiaResponse } from 'lithia';

export function successResponse(data: any, message?: string) {
  return {
    success: true,
    data,
    message: message || 'Operation successful'
  };
}

export function errorResponse(error: string, statusCode = 400) {
  return {
    success: false,
    error,
    statusCode
  };
}
src/routes/api/users/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';
import { successResponse, errorResponse } from '@/utils/response';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  try {
    const data = await getData();
    res.json(successResponse(data));
  } catch (error) {
    res.status(500).json(errorResponse('Failed to get data', 500));
  }
};

CORS Helpers

Handle Cross-Origin Resource Sharing with built-in helpers.

Setting up CORS through the res object will override the CORS settings in the lithia.config.ts file.

src/routes/api/cors/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (req: LithiaRequest, res: LithiaResponse) => {
  // Set CORS headers with helper method
  res.cors({
    origin: '*',
    methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
    headers: ['Content-Type', 'Authorization'],
    credentials: false
  });
  
  // Handle preflight requests
  if (req.method === 'OPTIONS') {
    res.status(200).end();
    return;
  }
  
  res.json({ message: 'CORS enabled' });
};
src/routes/api/secure/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (req: LithiaRequest, res: LithiaResponse) => {
  // Restrictive CORS for specific origins
  res.cors({
    origin: ['https://myapp.com', 'https://www.myapp.com'],
    methods: ['GET', 'POST'],
    headers: ['Content-Type'],
    credentials: true
  });
  
  res.json({ message: 'Secure CORS' });
};

Cache Helpers

Set cache headers with built-in helpers

src/routes/api/cache/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Set cache headers with helper method
  res.cache({
    maxAge: 3600, // 1 hour
    private: true,
    mustRevalidate: true,
    etag: 'abc123'
  });
  
  res.json({ message: 'Cached response' });
};
src/routes/api/no-cache/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Disable caching
  res.cache({
    noCache: true,
    noStore: true
  });
  
  res.json({ message: 'No cache response' });
};

File Helpers

Send files with built-in helpers

src/routes/download/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Send file as download
  res.download('./public/document.pdf', 'my-document.pdf', {
    root: './',
    headers: {
      'Content-Type': 'application/pdf'
    }
  });
};
src/routes/image/route.get.ts
import type { LithiaRequest, LithiaResponse } from 'lithia';

export default async (_req: LithiaRequest, res: LithiaResponse) => {
  // Send file with appropriate headers
  res.sendFile('./public/image.jpg', {
    root: './',
    cache: true,
    headers: {
      'Content-Type': 'image/jpeg'
    }
  });
};