Skip to content

Commit

Permalink
📄 Added templates example project
Browse files Browse the repository at this point in the history
  • Loading branch information
lukecarr committed Nov 19, 2021
1 parent 8429209 commit 7d5795f
Show file tree
Hide file tree
Showing 4 changed files with 439 additions and 3 deletions.
24 changes: 21 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
[![Dependencies](https://img.shields.io/badge/dependencies-0-success)](https://www.npmjs.com/package/@moducate/houston?activeTab=dependencies)
[![Tree-shakeable](https://img.shields.io/badge/esm-tree--shakeable-success)](#)

- 📃 **Fully compliant.** Fully compliant with the [RFC 7807 specification](https://datatracker.ietf.org/doc/html/rfc7807)!
- 📋 **Fully compliant.** Fully compliant with the [RFC 7807 specification](https://datatracker.ietf.org/doc/html/rfc7807)!
-**Configurable.** Supports [custom JSON stringify functions](#optionsstringify)!
- 📃 **Support for templating.** Create [template functions](#templates) to generate errors from parameters!
- 🐁 **Tiny.** Total bundle size comes in at [< 300B minified + gzipped](https://bundlephobia.com/package/moducate/houston)!
- 💡 **Lightweight.** Tiny (see above), zero dependencies, and tree-shakeable!
- 💪 **TypeScript.** Fully typed and self-documenting!
- 🎉 **Support for Node.js >=10.24!**
-**Configurable.** Supports [custom JSON stringify functions](#optionsstringify)!

## 🚀 Quick Start

Expand Down Expand Up @@ -47,7 +48,7 @@ You can create error templates using the exported `withTemplate` function:
const { withTemplate } = require("@moducate/houston");
const app = require("express")();

const [withUserNotFound, rawUserNotFound] = withTemplate<{ userId: number }>(({ userId }) => ({
const [withUserNotFound, rawUserNotFound] = withTemplate(({ userId }) => ({
type: "https://example.com/user-not-found",
status: 404,
instance: `/users/${userId}`,
Expand Down Expand Up @@ -76,6 +77,19 @@ const [, withNotFound] = withTemplate(() => ({ type: "https://example.com/not-fo
// => Returns the raw function for transforming an object
```

### 💪 TypeScript

`withTemplate` supports TypeScript generics so you can have type definitions for your template's parameters:

```ts
const [withUserNotFound] = withTemplate<{ userId: number }>(({ userId }) => ({
type: "https://example.com/user-not-found",
status: 404,
instance: `/users/${userId}`,
}));
// => withUserNotFound's second parameter (`params`) now has the type `{ userId: number }`
```

## 🏷 MIME Type

The exported `mime` constant can be used to obtain the media/MIME type for RFC 7807 JSON errors.
Expand Down Expand Up @@ -156,6 +170,10 @@ app.get("/not-found", (_, reply) => {

See the `examples/fast-json-stringify` directory for an example project using Houston with Fastify and fast-json-stringify.

### Templates

See the `examples/templates` directory for an example project using Houston's templating functionality with Express.

## ⚖ License

Houston is licensed under the [`MIT License`](LICENSE).
8 changes: 8 additions & 0 deletions examples/templates/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "templates",
"private": true,
"dependencies": {
"express": "^4.17.1",
"@moducate/houston": "../.."
}
}
39 changes: 39 additions & 0 deletions examples/templates/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const { withTemplate } = require('@moducate/houston')
const app = require('express')()

const books = [
{
id: '1',
name: 'The Da Vinci Code',
author: 'Dan Brown',
publisher: 'Transworld'
},
{
id: '2',
name: 'Harry Potter and the Deathly Hallows',
author: 'J.K. Rowling',
publisher: 'Bloomsbury'
}
]

const [withBookNotFound] = withTemplate(({ bookId }) => ({
type: 'https://express.example.com/not-found',
status: 404,
instance: `/books/${bookId}`,
title: 'Book not found.',
detail: `No book was found with the ID '${bookId}'.`,
}))

app.get('/books', (_, res) => {
return res.json(books)
})

app.get('/books/:id', ({ params }, res) => {
const book = books.find(x => x.id === params.id)
if (book) {
return res.json(book)
}
return withBookNotFound(res, { bookId: params.id })
})

app.listen(3000)
Loading

0 comments on commit 7d5795f

Please sign in to comment.