# Routing

## File-based Routing

The APIs are located in your `/app/api`directory.

It autoloads all the files that live in this directory if it follows the format below.

{% code title="app/api/accounts/index.ts" lineNumbers="true" %}

```typescript
export default async function Route (instance: FastifyInstance) {
    instance.get('/api/v1/account', handler);
    
    async function handler(request, reply) {
        console.log(request);
        reply.status(204);
    }
}
```

{% endcode %}

This file is automatically loaded when novel starts.&#x20;

It still needs you to specify the endpoint of the API via [Fastify's routing](https://fastify.dev/docs/latest/Reference/Routes/).

> `instance`is an instance of a Fastify plugin. All Fastify interfaces are available here and additional ones that are discussed below.

Below are all the examples of valid route registrations

{% code lineNumbers="true" %}

```typescript
instance.get('/api/v1/account', handler);
instance.post('/api/v1/account', handler);
instance.patch('/api/v1/account', handler);
instance.head('/api/v1/account', handler);
instance.put('/api/v1/account', handler);
instance.delete('/api/v1/account', handler);
instance.options('/api/v1/account', handler);
instance.any('/api/v1/account', handler);

// you can add fastify route options as well
instance.get('/api/v1/account', fastifyRouteOptions, handler);
```

{% endcode %}

The routes are attached in their own scope&#x20;

{% embed url="<https://docs.novel.dev/guides/knowledge-base/novel-server/creating-a-rest-endpoint>" %}

## Built-in Routes

Novel comes with plenty of built-in routes that are created to glue together various SaaS functionalities.

These routes are available under `/app/api/internal/v1`and exposed under `/api/v1`.&#x20;

You can inspect these routes using the API reference in this documentation, or the files in the Novel API repository

[See API Reference →](/novel-server/novel-api/api-reference.md)

See <https://github.com/madewithnovel/novel/tree/main/app/api/internal/v1>

## Protecting Routes

You can secure your endpoints by making use of the various ways Novel scopes requests. There are 2 standard modes: `cookie` and `api keys`.

{% embed url="<https://docs.novel.dev/guides/knowledge-base/novel-server/securing-an-endpoint>" %}

The functions below are called [Route Directives](/novel-server/routing/route-directives.md). Check other route directives available to you.

## Cookie

The cookie session allows all requests into the Novel API with the `session`cookie to be acknowledged and keep a session related to a user.

### `instance.authenticated()`

You can access this session via the request variable in your handler.

{% code title="app/api/accounts/index.ts" lineNumbers="true" %}

```typescript
export default async function Route (instance: FastifyInstance) {
    instance.get('/api/v1/account', handler);
    instance.authenticated();
    
    async function handler(request, reply) {
        console.log(request.session);
        reply.status(204);
    }
}
```

{% endcode %}

{% hint style="info" %}
These sessions are the same in both cookie and api key contexts.
{% endhint %}

There are also additional request variables available to you for convenience.

#### `request.account`&#x20;

This includes details on which user is accessing that request.

```typescript
request.account = {
    id: string,
    role: string,
    verified: boolean,
};
```

#### `request.org`

This includes details on which organization is being used by the current request

```typescript
request.org = {
    id: string,
}
```

{% embed url="<https://docs.novel.dev/novel-server/sessions>" %}

## Request  Context

Each route has access to a request context that uses Node's `async_hooks`, and `@fastify/request-context` library.

This allows Novel to tap into relevant context of the request outside of the request handler. For example, retrieving an account ID in a database model.

## Using API Keys

If you want to restrict endpoints based on API keys, you can use the directive below:

### `instance.authorized()`

{% code title="app/api/accounts/index.ts" lineNumbers="true" %}

```typescript
export default async function Route (instance: FastifyInstance) {
    instance.get('/api/v1/account', handler);
    instance.authorized();
    
    async function handler(request, reply) {
        console.log(request.session);
        reply.status(204);
    }
}
```

{% endcode %}

{% hint style="info" %}
These sessions are the same in both cookie and api key contexts.
{% endhint %}

This will check if the API key belongs to a specific user and fill in the relevant session variables like the above.

{% hint style="info" %}
You can use both `authorized` and `authenticated` directives in the same route definition.
{% endhint %}

## Changelog

* 2024-12-20 - Initial Documentation


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.novel.dev/novel-server/routing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
