npm package: @relab/nestjs-graphql
Description: GraphQL infrastructure for Nest.js
Author: Sergey Zwezdin
Latest version: 1.3.2

# @relab/nestjs-graphql

GraphQL infrastructure utilities and plugins for [NestJS](https://nestjs.com/) applications. This package provides decorators, helpers, and Apollo Server plugins to simplify and enhance GraphQL development, including batch loading, field selection, mapping, and observability.

## Features

- **Batch loading decorator** for efficient DataLoader integration in resolvers
- **Field selection decorator** to extract requested fields from GraphQL queries
- **Mapper and MapperSelect decorators** for type-safe mapping and field selection (e.g., for Prisma)
- **Apollo Server plugins**:
  - GraphiQL Playground integration
  - HTTP status code propagation for exceptions
  - Prometheus request metrics for queries and mutations

## Installation

```bash
pnpm add @relab/nestjs-graphql
# or
yarn add @relab/nestjs-graphql
# or
npm install @relab/nestjs-graphql
```

> **Note:** This package requires `@nestjs/common`, `@nestjs/core`, `@nestjs/graphql`, `@nestjs/apollo`, `graphql`, and (optionally) `prom-client` for metrics. Please ensure you use compatible versions with your NestJS setup.

## Usage

### Batch Loading with DataLoader

```typescript
import { Resolver, ResolveField, Parent } from '@nestjs/graphql';
import { GraphQLResolveFieldBatch, BatchLoader } from '@relab/nestjs-graphql';

@Resolver(() => Company)
export class CompanyResolver {
  @ResolveField(() => [BankAccount])
  bankAccounts(
    @Parent() company: Company,
    @GraphQLResolveFieldBatch() batch: BatchLoader<number, BankAccount>
  ): Promise<BankAccount[]> {
    return batch(async (companyIds, fields) => {
      // Implement batch loading logic here
    }).load(company.id);
  }
}
```

### Field Selection Decorator

```typescript
import { GraphQLFields } from '@relab/nestjs-graphql';

@Query(() => Company)
getCompany(@GraphQLFields() fields: string[]) {
  // 'fields' contains the requested fields in the query
}
```

### Mapper and MapperSelect Decorators

```typescript
import { Mapper, MapperSelect } from '@relab/nestjs-graphql';

@Mapper<DbCompany, Company>(db => ({
  id: db.id,
  name: db.name,
}))
@MapperSelect<Company, any>(fields => ({
  id: true,
  name: fields.includes('name'),
}))
@ObjectType()
export class Company {
  id: number;
  name: string;
}
```

#### Advanced: Accessing Registered Mappers

You can retrieve the registered mapper or select function for a class using the following helpers:

```typescript
import { getMapper, getMapperSelect } from '@relab/nestjs-graphql';

const companyMapper = getMapper<DbCompany, Company>(Company);
const companySelect = getMapperSelect<Company, any>(Company);
```

### Apollo Server Plugins

- **GraphiQLPlaygroundPlugin**: Adds a modern GraphiQL playground to your server.
- **HttpStatusCodePlugin**: Propagates HTTP status codes from thrown `HttpException`s to GraphQL responses.
- **RequestMetricsPlugin**: Exposes Prometheus metrics for GraphQL queries and mutations (requires `prom-client`).

#### Example Plugin Registration (Apollo Server)

Register plugins in the Apollo Server configuration:

```typescript
import { ApolloDriverConfig, ApolloDriver } from '@nestjs/apollo';
import { GraphQLModule } from '@nestjs/graphql';
import { GraphiQLPlaygroundPlugin, HttpStatusCodePlugin, RequestMetricsPlugin } from '@relab/nestjs-graphql';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      plugins: [
        new RequestMetricsPlugin(),
        new HttpStatusCodePlugin(),
        GraphiQLPlaygroundPlugin.forRoot({ title: 'My API Playground' }).useFactory(),
      ],
    }),
  ],
})
export class AppModule {}
```

## API Reference

### Exports

| Export                        | Description                                                                 |
|-------------------------------|-----------------------------------------------------------------------------|
| `BatchLoader`                 | Type for batch loading function for resolvers                               |
| `GraphQLResolveFieldBatch`    | Decorator for batch loading in resolvers                                    |
| `GraphQLField`                | Type for GraphQL field names                                                |
| `GraphQLFields`               | Decorator to extract requested fields from GraphQL queries                  |
| `Mapper`                      | Decorator to register a mapping function for a class                        |
| `MapperFunction`              | Type for mapping function                                                   |
| `getMapper`                   | Helper to retrieve a registered mapper                                      |
| `MapperSelect`                | Decorator to register a select/include function for a class                 |
| `MapperSelectFunction`        | Type for select/include function                                            |
| `getMapperSelect`             | Helper to retrieve a registered select/include function                     |
| `GraphiQLPlaygroundPlugin`    | Apollo Server plugin for GraphiQL playground                                |
| `GraphiQLOptions`             | Options for GraphiQL playground                                             |
| `HttpStatusCodePlugin`        | Apollo Server plugin for HTTP status code propagation                       |
| `RequestMetricsPlugin`        | Apollo Server plugin for Prometheus request metrics                         |

See the source code and TypeScript types for detailed API documentation and usage examples for each decorator and plugin.

## License

MIT