---
title: Request Handling | Advanced
description: How to handle requests in Qwik City, including REST endpoints, and middlewares.
contributors:
  - adamdbradley
  - manucorporat
  - mhevery
  - tzdesign
  - mrhoodz
  - hamatoyogi
  - jemsco
updated_at: '2023-07-01T18:35:24Z'
created_at: '2023-03-20T23:45:13Z'
---

# Request Handling

Each `layout.ts` and `index.ts` file inside the `src/routes` directory has the ability to access the current HTTP request, response, and URL. This allows you to retrieve and modify data, and even respond with custom content.

Qwik City implements a middleware system based on the hirarchy of the `src/routes` directory. The middleware system is used to handle HTTP requests and responses and is available to pages, layouts, and [endpoints](/docs/(qwikcity)/endpoints/index.mdx).

Each route can add HTTP request and response handlers, allowing developers to retrieve and modify data. The handlers can also be used by [endpoints](/docs/(qwikcity)/endpoints/index.mdx), which only respond with data rather than a page's HTML.

This feature enables you to handle any request event, have side effects on the request pipeline, just before you render the component and respond with custom content. It is available to pages, layouts and endpoint routes, but not on regular components.

## Request and Response Handlers

On pages, layouts, and [endpoints](/docs/(qwikcity)/endpoints/index.mdx), we can access request data by implementing request handler functions such as `onGet`, `onPost`, `onPut`, etc. These functions are executed according to the [HTTP method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) used for this route.

Additionally, an `onRequest` function can be used to handle any request method, rather than a specific one, in the form of a [middleware](/docs/(qwikcity)/middleware/index.mdx). For example, if both `onGet` and `onRequest` is provided, for a `GET` request, the `onGet` will be called. However, in this scenario, if a `POST` request method came in, then the `onRequest` handler would be called since an `onPost` was not provided.
The `onRequest` is available as a catch-all to any request methods that do not have a specific method.

```tsx
import type { RequestHandler } from '@builder.io/qwik-city';

export const onGet: RequestHandler<ProductData> = async ({ params }) => {
  // put your DB access here (hard coding data for simplicity)
  return {
    skuId: params.skuId,
    price: 123.45,
    description: `Description for ${params.skuId}`,
  };
};
```

## Request Event

The request handler functions receive a `RequestEvent` argument which has the following properties:

| Field      | Description                                                                   |
| ---------- | ----------------------------------------------------------------------------- |
| `request`  | The request object                                                            |
| `response` | The response object, which can be used to set response `headers` and `status` |
| `url`      | URL which includes `pathname`, `hostname`, etc.                               |
| `next`     | Next middleware function                                                      |
| `abort`    | Request abort function                                                        |
| `params`   | Custom user params found within the URL                                       |
| `cookie`   | Get and set cookies.                                                          |
| `platform` | Platform data object (useful for Cloudflare, Netlify, etc)                    |

### Cookie

```tsx
interface Cookie {
  get: (key: string) => CookieValue | null;
  set: (key: string, value: string | number | Record<string, any>, options?: CookieOptions) => void;
  delete: (key: string) => void;
  has: (key: string) => boolean;
}
```

**get**
Takes a string with the cookie name and returns the `CookieValue`, if present and null if not.

```tsx
interface CookieValue {
  value: string;
  json: <T = unknown>() => T;
  number: () => number;
}
```

A cookie value is a simple record with three fields:

1. `value`: Contains the cookie value as a string
2. `json()`: Runs `JSON.parse()` on the value and returns the result
3. `number()`: Runs `Number()` on the value and returns the result

**getAll**
Returns an object with all cookies, if any. _This is sometimes required if the names of cookies are unknown and must be parsed through._

**set**
Takes a key and value and creates a header that will be appended to the response. Value can be a `string | number | Record<string, any>`

As a third argument, you can optionally provide a `CookieOptions` record for setting additional fields.

```tsx
export interface CookieOptions {
  domain?: string;
  expires?: Date | string;
  httpOnly?: boolean;
  maxAge?: number | [number, 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks'];
  path?: string;
  sameSite?: 'lax' | 'none' | 'strict';
  secure?: boolean;
}
```

For more information on these attributes and their values, please refer to [the MDN article on the Set-Cookie header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes).

**delete**
Appends a header with the provided key to the cookie. The new header will have an expired date in the `expires` field, telling the browers to remove it.

```tsx
cookie.delete('my-cookie');
// equivalent to
cookie.set('my-cookie', 'deleted', new Date(0));
// or
cookie.set('my-cookie', '');
```

Optionally, you can set the path, sameSite and/or domain when deleting the cookie. If your cookie was created with a path/domain, you must set these fields for the deletion to take effect.

```tsx
cookie.delete('my-cookie', { domain: 'https://qwik.dev', path: '/docs/' });
```

**has**
A convenience method which returns true or false based on the presence of the provided key in cookie.

```tsx
cookie.has('my-cookie');
```
