Conditions:
validation via Joi
en utilisant Typescript
Serveur express
SWAGGER sur / api-docs
Tâche: SEC
Décision:
Vous devez d'abord décider de ce qui vient en premier: le schéma Joi, Swagger ou l'interface TypeScript. Il a été empiriquement établi que Joi devrait être rendu primaire.
1. Installation de tous les modules sur Express
npm install --save swagger-ui-express
Ajoutez des lignes à app.ts (index.ts):
import swaggerUI = require('swagger-ui-express')
import swDocument from './openapi'
...
app.use('/api-docs',swaggerUI.serve,swaggerUI.setup(swDocument))
2. Créez ./openapi.ts
. ( , ) SWAGGER-. openapi v3.0.0
:
import {swLoginRoute} from './routes/login'
const swagger = {
openapi: '3.0.0',
info: {
title: 'Express API for Dangle',
version: '1.0.0',
description: 'The REST API for Dangle Panel service'
},
servers: [
{
url: 'http://localhost:3001',
description: 'Development server'
}
],
paths: {
...swLoginRoute
},
}
export default swagger
.
3.
openapi-
./routes/login/index.ts:
import {swGetUserInfo} from './get-user-info'
import {swUpdateInfo} from './update-info'
export const swLoginRoute = {
"/login": {
"get": {
...swGetUserInfo
},
"patch": {
...swUpdateInfo
}
}
}
/login, : get patch. get-user-into.ts update-info.ts. .
4.
, Joi-.
.
: , .
update-info.ts, ( ):
import schema, {joiSchema} from './update-info.spec/schema'
export const swUpdateInfo = {
"summary": "update the user info",
"tags": [
"login"
],
"parameters": [
{
"name": "key",
"in": "header",
"schema": {
"type": "string"
},
"required": true
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
...schema
}
}
}
},
"responses": {
"200": {
"description": "Done"
},
"default": {
"description": "Error message"
}
}
}
// ...
JSON- Swagger-, . :
"schema": {
...schema
}
.
Joi- :
await joiSchema.validateAsync(req.body)
4. Joi-
Joi:
npm install --save joi joi-to-swagger
:
const joi = require('joi')
const j2s = require('joi-to-swagger')
// Joi
export const joiSchema = joi.object().keys({
mode: joi.string().required(),
email: joi.string().email()
})
// end of Joi
const schema = j2s(joiSchema).swagger
export default schema
Joi- swagger-.
, SWAGGER- . TypeScript-
5. TypeScript
npm install --save-dev gulp @babel/register @babel/plugin-proposal-class-properties @babel/preset-env @babel/preset-typescript
Gulp. , . gulpfile.ts :
const gulp = require('gulp')
const through = require('through2')
import { compile } from 'json-schema-to-typescript'
const fs = require('fs')
const endName = "schema.ts"
const routes = `./routes/**/*.spec/*${endName}`
function path(str: string) : string
{
let base = str
if(base.lastIndexOf(endName) != -1)
base = base.substring(0, base.lastIndexOf(endName))
return base
}
gulp.task('schema', () => {
return gulp.src(routes)
.pipe(through.obj((chunk, enc, cb) => {
const filename = chunk.path
import(filename).then(schema => { // dynamic import
console.log('Converting', filename)
compile(schema.default, `IDTO`)
.then(ts => {
//console.log(path(filename).concat('interface.ts'), ts)
fs.writeFileSync(path(filename).concat('interface.ts'), ts)
})
})
cb(null, chunk)
}))
})
// watch service
const { watch, series } = require('gulp')
exports.default = function() {
watch(routes, series('schema'))
}
Le script contourne tous les sous-répertoires nommés * .spec dans le répertoire du routeur. Là, il recherche les fichiers avec les noms * schema.ts et crée un certain nombre de fichiers avec les noms * interface.ts
Conclusion
Bien sûr, ces objets JSON volumineux et complexes avec la spécification openAPI sont effrayants, mais vous devez comprendre qu'ils ne sont pas écrits à la main, mais générés par l' utilitaire SWAGGER.
En raison de l'inexpérience, le réglage initial du mécanisme peut prendre un certain temps, mais cela économisera des centaines d'heures qui pourraient être consacrées à la routine!