Skip to content

Commit

Permalink
improved schema preprocessor and Date object handling (validation/s…
Browse files Browse the repository at this point in the history
…erialization) for response bodies (#499)

* CoerceComponents feature as expected in #353
We can cast data from request to object or transform object to string (or other type) in response.
Documentation modified and an example project created

* Issue on Typescript Options inheritance

* Patch AJV cache integration issue. AJV has a cache by schema description. We must add an unique ID field in schema description in order to have a specific schema description for each component
+
Test added coercecomponents.spec.ts
+ example modified in order to expose a date

* Change Test name to "coercecomponents". I missed to change from the example

* - Changes `coerceComponents` to `schemaObjectMapper`
- Fix function names serialize and deserialize => To be clear for everybody on which functions are executed on requests and responses, it's now `deserializeRequestComponent` and `serializeResponseComponent`

* Move example resources `7-coerce-components` to `7-schema-object-mapper`

* update naming and type declarations

* doc: update documentation

* traverse spec

* update preprocessor

* travserse via Node abstraction

* traverse and update both schemas

* finish one pass traversal to modified req and res schemas independently

* doc: remove schemaObjectMapper from readme

* doc: remove schemaObjectMapper from README

* fix: update method name

* cleanup

* rename preprocessor

* rename var

* sample built-in date-time formatter

* fix: types

* feat: provide opt-in option responseValidation serialization

* feat: handle date and date-time

* doc: update README

* fix: add example - Date serialization in responses

* doc: update README

* feat: add date serialization example

* doc: update README

* chore: remove commented code

* feat: handle Date or date string automatically

* add format metadata to Serializer

Co-authored-by: Pierre Le Roux <pilerou@gmail.com>
  • Loading branch information
cdimascio and pilerou authored Dec 26, 2020
1 parent e8d6a37 commit e08f45a
Show file tree
Hide file tree
Showing 20 changed files with 7,579 additions and 365 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1220,4 +1220,4 @@ We plan to publicize a variety of links here.

[MIT](LICENSE)

<a href="https://www.buymeacoffee.com/m97tA5c" target="_blank"><img src="https://bmc-cdn.nyc3.digitaloceanspaces.com/BMC-button-images/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;" ></a>
<a href="https://www.buymeacoffee.com/m97tA5c" target="_blank"><img src="https://bmc-cdn.nyc3.digitaloceanspaces.com/BMC-button-images/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;" ></a>
8 changes: 8 additions & 0 deletions assets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,11 @@ app.use((err, req, res, next) => {
```

_**Important:** Ensure express is configured with all relevant body parsers. Body parser middleware functions must be specified prior to any validated routes. See an [example](#example-express-api-server)_.

## [Documentation](https://github.com/cdimascio/express-openapi-validator#readme)

See the [full documentation](https://github.com/cdimascio/express-openapi-validator#readme)

## License

MIT
27 changes: 27 additions & 0 deletions examples/7-response-date-serialization/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# example

## Install

```shell
npm run deps && npm i
```

## Run

From this `7-schema-object-mapper` directory, run:

```shell
npm start
```

## Try

```shell

## call pets
## the call below should return 400 since it requires additional parameters
curl http://localhost:3000/v1/pets?type=dog&limit=3

## Get the first item id
curl http://localhost:3000/v1/pets/<first item id>
```
50 changes: 50 additions & 0 deletions examples/7-response-date-serialization/api.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
openapi: '3.0.0'
info:
version: 1.0.0
title: Swagger Petstore schemaObjectMapper variant
description: A sample API
termsOfService: http://swagger.io/terms/
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
- url: /v1
paths:
/date-time:
get:
responses:
200:
description: date-time handler
content:
application/json:
schema:
type: object
properties:
created_at:
type: string
format: date-time
id:
type: number
/date:
get:
responses:
200:
description: date handler
content:
application/json:
schema:
$ref: '#/components/schemas/User'

components:
schemas:
Date:
type: string
format: date
User:
type: object
properties:
id:
type: number
created_at:
$ref: "#/components/schemas/Date"

57 changes: 57 additions & 0 deletions examples/7-response-date-serialization/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const http = require('http');
const OpenApiValidator = require('express-openapi-validator');

const port = 3000;
const app = express();
const apiSpec = path.join(__dirname, 'api.yaml');

// 1. Install bodyParsers for the request types your API will support
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.text());
app.use(bodyParser.json());

// Optionally serve the API spec
app.use('/spec', express.static(apiSpec));

// 2. Install the OpenApiValidator on your express app
app.use(
OpenApiValidator.middleware({
apiSpec,
validateResponses: true,
}),
);
// 3. Add routes
app.get('/v1/ping', function (req, res, next) {
res.send('pong');
});

app.get('/v1/date-time', function (req, res, next) {
res.json({
id: 1,
created_at: new Date(),
});
});

app.get('/v1/date', function (req, res, next) {
res.json({
id: 1,
created_at: new Date(),
});
});

// 4. Create a custom error handler
app.use((err, req, res, next) => {
// format errors
res.status(err.status || 500).json({
message: err.message,
errors: err.errors,
});
});

http.createServer(app).listen(port);
console.log(`Listening on port ${port}`);

module.exports = app;
Loading

0 comments on commit e08f45a

Please sign in to comment.