Make NestJS return RFC-7807-compliant HTTP problem details.
A NestJS exception filter to convert JSON responses to RFC-7807-compliant format. This standardizes HTTP responses and sets Content-Type
to application/problem+json
Install the library with:
# npm
npm i nest-problem-details-filter
# or, pnpm
pnpm i nest-problem-details-filter
Then check NestJS documentation on how to bind exception filters.
In main.ts
add app.useGlobalFilters(new HttpExceptionFilter(app.getHttpAdapter()))
as the following
import { NestFactory } from '@nestjs/core';
import { HttpExceptionFilter } from 'nest-problem-details-filter';
import { AppModule } from './app/app.module';
async function bootstrap() {
...
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new HttpExceptionFilter(app.getHttpAdapter()));
...
}
HttpExceptionFilter
accepts a base URI for if you want to return absolute URIs for your problem types, e.g:
app.useGlobalFilters(new HttpExceptionFilter('https://example.org'));
Will return:
{
"type": "https://example.org/not-found",
"title": "Dragon not found",
"status": 404,
"detail": "Could not find any dragon with ID: 99"
}
The library can be imported as a module, and then can use HTTP_EXCEPTION_FILTER_KEY
to set APP_FILTER
import { APP_FILTER } from '@nestjs/core';
import {
NestProblemDetailsModule,
HTTP_EXCEPTION_FILTER_KEY,
} from 'nest-problem-details-filter';
@Module({
imports: [NestProblemDetailsModule],
...
providers: [
{
provide: APP_FILTER,
useExisting: HTTP_EXCEPTION_FILTER_KEY,
},
...
],
})
See:
# curl -i http://localhost:3333/api/dragons/99?title=true&details=true
HTTP/1.1 404 Not Found
Content-Type: application/problem+json; charset=utf-8
Content-Length: 109
...
{
"type": "not-found",
"title": "Dragon not found",
"status": 404,
"detail": "Could not find any dragon with ID: 99"
}
# Source: https://opensource.zalando.com/restful-api-guidelines/problem-1.0.1.yaml
Problem:
type: object
properties:
type:
type: string
format: uri-reference
description: >
A URI reference that uniquely identifies the problem type only in the
context of the provided API. Opposed to the specification in RFC-7807,
it is neither recommended to be dereferencable and point to a
human-readable documentation nor globally unique for the problem type.
default: 'about:blank'
example: '/problem/connection-error'
title:
type: string
description: >
A short summary of the problem type. Written in English and readable
for engineers, usually not suited for non technical stakeholders and
not localized.
example: Service Unavailable
status:
type: integer
format: int32
description: >
The HTTP status code generated by the origin server for this occurrence
of the problem.
minimum: 100
maximum: 600
exclusiveMaximum: true
example: 503
detail:
type: string
description: >
A human readable explanation specific to this occurrence of the
problem that is helpful to locate the problem and give advice on how
to proceed. Written in English and readable for engineers, usually not
suited for non technical stakeholders and not localized.
example: Connection to database timed out
instance:
type: string
format: uri-reference
description: >
A URI reference that identifies the specific occurrence of the problem,
e.g. by adding a fragment identifier or sub-path to the problem type.
May be used to locate the root of this problem in the source code.
example: '/problem/connection-error#token-info-read-timed-out'
- IETF RFC-7807: Problem Details for HTTP APIs
- Zalando RESTful API:
- And of course, Nest's awesome community:
This project is licensed under the MIT License - see the LICENSE file for details