# Request Helpers

This is a catalog of available convenience methods available in Novel registered using Fastify's request and reply decorators.

## Request

### `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,
}
```

{% hint style="warning" %}
`request.account`and `request.org` are both [getters and setters](https://fastify.dev/docs/latest/Reference/Decorators/#getters-and-setters) and will trigger errors if accessed outside of `instance.authorized()`or `instance.authenticated()`directives.
{% endhint %}

### `await request.can(action: string, subject: any, fields: string[])`

Discussed in [Authorization](/novel-server/authorization.md)

A convenience method that allows you to check if the currently logged in user is allowed to take `action`towards the specific `subject`.

This uses the CASL `can`signature.

{% code title="app/api/v1/your-route/index.ts" lineNumbers="true" %}

```typescript
export default function Route(instance) {
    instance.authenticated();
    instance.get('/your/route', handler);
    
    async function handler (request) {
        await request.can('read', 'projects');
        reply.send('ONLY FOR SESSIONS WITH projects:read PERMISSION');
    }
}
```

{% endcode %}

See <https://github.com/madewithnovel/novel/blob/main/packages/novel/lib/session.js#L196>

### `await request.cannot(action: string, subject: any, fields: string[])`

Discussed in [Authorization](/novel-server/authorization.md)

This is the inverse of `await request.can()` above.

### `await request.verified()`

Check if the currently logged in user has a `verified`status.

{% code title="app/api/v1/your-route/index.ts" lineNumbers="true" %}

```typescript
export default function Route(instance) {
    instance.authorized();
    instance.get('/your/route', handler);
    
    async function handler (request) {
        await request.verified();
        reply.send('ONLY FOR AUTHENTICATED API KEYS');
    }
}
```

{% endcode %}

### `await request.subscribed()`

Check if the currently logged in organization has an active subscription.

{% code title="app/api/v1/your-route/index.ts" lineNumbers="true" %}

```typescript
export default function Route(instance) {
    instance.authorized();
    instance.get('/your/route', handler);
    
    async function handler (request) {
        await request.subscribed();
        reply.send('ONLY FOR SUBSCRIBED ORGANIZATIONS');
    }
}
```

{% endcode %}

### `request.ua()`

A convenience method that exposes an object that has the user-agent parsed by the `my-ua-parser`library.

{% code title="app/api/v1/your-route/index.ts" lineNumbers="true" %}

```typescript
export default function Route(instance) {
    instance.get('/your/route', handler);
    
    async function handler (request) {
        return request.ua();
    }
}
```

{% endcode %}

Check the[ library definition for the ua object](https://github.com/mcollina/my-ua-parser#constructor).

## Reply

### `reply.error(error: FastifyError)`

A response builder that consolidates errors and produces an error format unique to Novel.

See <https://github.com/madewithnovel/novel/blob/main/packages/novel/lib/server.js#L158>

### `await reply.uncache(key: string, options?: CacheOptions)`

This is a decorator to reply that you can use to manually purge a cached response.

{% code title="app/api/v1/your-route/index.ts" lineNumbers="true" %}

```typescript
export default function Route(instance) {
    instance.get('/your/route', handler);
    
    async function handler (request, reply) {
        await request.cache('custom-key');
        // do some specific logic
        reply.send('OK');
        await reply.uncache('custom-key');
    }
}
```

{% endcode %}

{% embed url="<https://docs.novel.dev/novel-server/routing/route-directives#cacheoptions>" %}

## 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/request-helpers.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.
