> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Antony-Figueroa/my-evershop-app/llms.txt
> Use this file to discover all available pages before exploring further.

# Routing

> Configure API routes and page rendering with route.json files

# Routing

EverShop uses a file-based routing system with `route.json` configuration files. These files define how API endpoints are accessed and control the middleware execution order.

## route.json Files

Every API endpoint in EverShop requires a `route.json` file that specifies:

* HTTP methods allowed
* URL path
* Access control (public/private)

### Basic Structure

```json route.json theme={null}
{
  "methods": ["GET", "POST"],
  "path": "/api/endpoint",
  "access": "public"
}
```

## Configuration Properties

### methods

HTTP methods that the endpoint accepts:

```json theme={null}
{
  "methods": ["POST"]
}
```

```json theme={null}
{
  "methods": ["GET", "POST", "PUT", "DELETE"]
}
```

<Note>
  Only the methods listed in `methods` will be accepted. Other methods will return a 405 Method Not Allowed error.
</Note>

### path

The URL path where the endpoint is accessible:

```json theme={null}
{
  "path": "/foos"
}
```

```json theme={null}
{
  "path": "/api/products/:id"
}
```

<Tip>
  Use Express-style path parameters with `:paramName` for dynamic routes.
</Tip>

### access

Controls authentication requirements:

```json theme={null}
{
  "access": "public"   // No authentication required
}
```

```json theme={null}
{
  "access": "private"  // Authentication required
}
```

## Middleware Execution Order

EverShop uses filename conventions to control middleware execution order. Files are executed alphabetically, and you can use brackets `[name]` to specify dependencies.

### Naming Convention

Format: `[prerequisite]handlerName.ts`

The name in brackets runs **before** the main handler.

### Example: Body Parser Middleware

From the sample extension:

```plaintext extensions/sample/src/api/createFoo/ theme={null}
├── route.json
├── bodyParser.ts
└── [bodyParser]createFoo.ts
```

<Steps>
  ### First: bodyParser.ts runs

  ```typescript bodyParser.ts theme={null}
  import bodyParser from 'body-parser';

  export default (request, response, next) => {
    bodyParser.json({ inflate: false })(request, response, next);
  };
  ```

  ### Then: \[bodyParser]createFoo.ts runs

  ```typescript [bodyParser]createFoo.ts theme={null}
  import { EvershopRequest, EvershopResponse } from '@evershop/evershop';

  export default (request: EvershopRequest, response: EvershopResponse, next) => {
    const { name, description } = request.body;  // Body is now parsed!

    if (!name || !description) {
      return response
        .status(400)
        .json({ error: 'Name and description are required' });
    }

    const newFoo = {
      id: Date.now(),
      name,
      description
    };

    response.status(201).json({
      success: true,
      data: { foo: newFoo }
    });
  };
  ```

  ### Configure the route

  ```json route.json theme={null}
  {
    "methods": ["POST"],
    "path": "/foos",
    "access": "private"
  }
  ```
</Steps>

## Complete API Endpoint Example

Here's the full structure for the `createFoo` endpoint:

```plaintext theme={null}
extensions/sample/src/api/createFoo/
├── route.json                    # Route configuration
├── bodyParser.ts                 # Middleware: parse JSON body
└── [bodyParser]createFoo.ts      # Handler: create new foo
```

<CodeGroup>
  ```json route.json theme={null}
  {
    "methods": ["POST"],
    "path": "/foos",
    "access": "private"
  }
  ```

  ```typescript bodyParser.ts theme={null}
  import bodyParser from 'body-parser';

  export default (request, response, next) => {
    bodyParser.json({ inflate: false })(request, response, next);
  };
  ```

  ```typescript [bodyParser]createFoo.ts theme={null}
  import { EvershopRequest, EvershopResponse } from '@evershop/evershop';

  export default (request: EvershopRequest, response: EvershopResponse, next) => {
    const { name, description } = request.body;

    if (!name || !description) {
      return response
        .status(400)
        .json({ error: 'Name and description are required' });
    }

    const newFoo = {
      id: Date.now(),
      name,
      description
    };

    console.log('Creating new foo:', newFoo);

    response.status(201).json({
      success: true,
      data: { foo: newFoo }
    });
  };
  ```
</CodeGroup>

## Middleware Chain Examples

### Single Middleware

```plaintext theme={null}
api/getProduct/
├── route.json
└── getProduct.ts
```

No dependencies, just a simple handler.

### Two Middleware

```plaintext theme={null}
api/createOrder/
├── route.json
├── validateInput.ts
└── [validateInput]createOrder.ts
```

Execution order:

1. `validateInput.ts` - Validates request data
2. `[validateInput]createOrder.ts` - Creates the order

### Three Middleware

```plaintext theme={null}
api/updateProduct/
├── route.json
├── authenticate.ts
├── [authenticate]validatePermissions.ts
└── [authenticate][validatePermissions]updateProduct.ts
```

Execution order:

1. `authenticate.ts` - Verify user is logged in
2. `[authenticate]validatePermissions.ts` - Check user has permission
3. `[authenticate][validatePermissions]updateProduct.ts` - Update the product

<Note>
  Middleware in brackets must exist as separate files. The files are executed in dependency order, not alphabetically.
</Note>

## Request and Response Types

EverShop provides TypeScript types for Express request and response objects:

```typescript theme={null}
import { EvershopRequest, EvershopResponse } from '@evershop/evershop';

export default (
  request: EvershopRequest, 
  response: EvershopResponse, 
  next
) => {
  // Access request properties
  const { body, params, query, headers } = request;
  
  // Send responses
  response.status(200).json({ success: true });
  response.status(400).json({ error: 'Bad request' });
  response.status(500).json({ error: 'Server error' });
  
  // Call next middleware
  next();
};
```

## Common Patterns

### Public API Endpoint

```json route.json theme={null}
{
  "methods": ["GET"],
  "path": "/api/products",
  "access": "public"
}
```

Anyone can access this endpoint without authentication.

### Private API Endpoint

```json route.json theme={null}
{
  "methods": ["POST"],
  "path": "/api/orders",
  "access": "private"
}
```

Requires authentication. EverShop automatically checks for valid session/token.

### RESTful Resource

```plaintext theme={null}
extensions/myExtension/src/api/
├── getProducts/
│   ├── route.json          # GET /api/products
│   └── getProducts.ts
├── getProduct/
│   ├── route.json          # GET /api/products/:id
│   └── getProduct.ts
├── createProduct/
│   ├── route.json          # POST /api/products
│   └── createProduct.ts
├── updateProduct/
│   ├── route.json          # PUT /api/products/:id
│   └── updateProduct.ts
└── deleteProduct/
    ├── route.json          # DELETE /api/products/:id
    └── deleteProduct.ts
```

## Page Routing

While API endpoints use `route.json`, page components use a different system based on directory structure and the `layout` export.

### Page Areas

Pages are organized by "areas" - logical groupings based on where/when they render:

```plaintext theme={null}
src/pages/
├── all/              # Renders on all pages
├── homepage/         # Renders on homepage only
├── productPage/      # Renders on product detail pages
├── checkout/         # Renders on checkout pages
└── account/          # Renders on account pages
```

### Layout Export

The `layout` export determines where a component renders:

```typescript theme={null}
export const layout = {
  areaId: 'content',     // Which area to render in
  sortOrder: 10          // Order within that area
};
```

<Tip>
  Lower `sortOrder` numbers render first. Use multiples of 10 (10, 20, 30) to leave room for insertions.
</Tip>

### Common Area IDs

| Area ID                 | Description               |
| ----------------------- | ------------------------- |
| `header`                | Top of all pages          |
| `footer`                | Bottom of all pages       |
| `content`               | Main content area         |
| `sidebar`               | Sidebar area              |
| `productPageBottom`     | Below product details     |
| `checkoutPaymentMethod` | Payment method selection  |
| `checkoutShipping`      | Shipping method selection |

## Best Practices

<Accordion title="Use descriptive endpoint names">
  Name your API directories and files clearly:

  * Good: `createOrder`, `updateProduct`, `deleteUser`
  * Bad: `handler`, `endpoint1`, `api`
</Accordion>

<Accordion title="Validate input in middleware">
  Create separate validation middleware:

  ```plaintext theme={null}
  api/createProduct/
  ├── route.json
  ├── validateProduct.ts
  └── [validateProduct]createProduct.ts
  ```
</Accordion>

<Accordion title="Handle errors consistently">
  Return appropriate HTTP status codes:

  ```typescript theme={null}
  // 400 - Bad request (validation errors)
  response.status(400).json({ error: 'Invalid input' });

  // 401 - Unauthorized (not logged in)
  response.status(401).json({ error: 'Authentication required' });

  // 403 - Forbidden (logged in but no permission)
  response.status(403).json({ error: 'Permission denied' });

  // 404 - Not found
  response.status(404).json({ error: 'Resource not found' });

  // 500 - Server error
  response.status(500).json({ error: 'Internal server error' });
  ```
</Accordion>

<Accordion title="Use TypeScript for type safety">
  Always import and use EverShop types:

  ```typescript theme={null}
  import { EvershopRequest, EvershopResponse } from '@evershop/evershop';

  type RequestBody = {
    name: string;
    description: string;
  };

  export default (
    request: EvershopRequest<RequestBody>,
    response: EvershopResponse,
    next
  ) => {
    // TypeScript knows request.body.name is a string
  };
  ```
</Accordion>

## Testing Routes

### Using curl

```bash theme={null}
# POST request
curl -X POST http://localhost:3000/foos \
  -H "Content-Type: application/json" \
  -d '{"name":"Test","description":"A test foo"}'

# GET request
curl http://localhost:3000/api/products

# With authentication
curl http://localhost:3000/api/orders \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Using Postman or Insomnia

1. Set the HTTP method (GET, POST, etc.)
2. Enter the URL: `http://localhost:3000/foos`
3. Add headers (e.g., `Content-Type: application/json`)
4. Add body (for POST/PUT requests)
5. Send the request

## Next Steps

* Learn about [Extensions](/concepts/extensions) for organizing your code
* Understand [GraphQL API](/concepts/graphql) for alternative data fetching
* Explore [Themes](/concepts/themes) for page component rendering
