備忘録代わりとして書きます。
間違い、より楽なやり方もあると思いますのでご指摘大歓迎です。
#概要
openapi3.0でYAMLファイルを書き、
Swagger EditorのGenerate Server機能を用いてNode.jsを自動生成し、
HerokuへデプロイしてMock Serverにしようとしました。
#やり方
Mock Serverコードを記述したらGenerate Server > nodejs-serverを選択し、サーバコードをダウンロードする。
ダウンロードしたNode.jsを解凍し、index.jsを変更する。
'use strict';
var path = require('path');
var http = require('http');
var oas3Tools = require('oas3-tools');
//var serverPort = 8080;//ここを変更
var serverPort = process.env.PORT || 8080;
// swaggerRouter configuration
var options = {
routing: {
controllers: path.join(__dirname, './controllers')
},
};
var expressAppConfig = oas3Tools.expressAppConfig(path.join(__dirname, 'api/openapi.yaml'), options);
var app = expressAppConfig.getApp();
// Initialize the Swagger middleware
http.createServer(app).listen(serverPort, function () {
console.log('Your server is listening on port %d (http://localhost:%d)', serverPort, serverPort);
console.log('Swagger-ui is available on http://localhost:%d/docs', serverPort);
});
#発生した問題
Herokuへデプロイし、確認した所
Access to XMLHttpRequest at 'http://localhost:8081' from origin 'https://test-app-20210113.herokuapp.com/
' has been blocked by CORS policy:
のようなエラーが発生。
調べてみたところ、CORS policyというものが問題のよう。
cors modulesをインポートしてexpress moduleを使う際に
app.(use(cors))とすると解決できるようですが、そもそもexpress moduleはどこ・・・
#解決法
index.jsを読んでみるとoas3Toolsという独自モジュールを使っているらしい。
node_modules -> oas3-tools -> dist -> middleware ->express.app.config.jsにcorsをインポート
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExpressAppConfig = void 0;
const express = require("express");
const cors = require("cors");//追加
const cookieParser = require("cookie-parser");
const bodyParser = require("body-parser");
const swagger_ui_1 = require("./swagger.ui");
const swagger_router_1 = require("./swagger.router");
const swagger_parameters_1 = require("./swagger.parameters");
const logger = require("morgan");
const fs = require("fs");
const jsyaml = require("js-yaml");
const OpenApiValidator = require("express-openapi-validator");
class ExpressAppConfig {
constructor(definitionPath, appOptions) {
this.definitionPath = definitionPath;
this.routingOptions = appOptions.routing;
this.setOpenApiValidatorOptions(definitionPath, appOptions);
this.app = express();
const spec = fs.readFileSync(definitionPath, 'utf8');
const swaggerDoc = jsyaml.safeLoad(spec);
this.app.use(cors());//追加
this.app.use(bodyParser.urlencoded());
this.app.use(bodyParser.text());
this.app.use(bodyParser.json());
this.app.use(this.configureLogger(appOptions.logging));
this.app.use(express.json());
this.app.use(express.urlencoded({ extended: false }));
this.app.use(cookieParser());
const swaggerUi = new swagger_ui_1.SwaggerUI(swaggerDoc, appOptions.swaggerUI);
this.app.use(swaggerUi.serveStaticContent());
this.app.use(OpenApiValidator.middleware(this.openApiValidatorOptions));
this.app.use(new swagger_parameters_1.SwaggerParameters().checkParameters());
this.app.use(new swagger_router_1.SwaggerRouter().initialize(this.routingOptions));
this.app.use(this.errorHandler);
}
gitignoreからnode_modulesを削除し、この状態でHerokuへデプロイした所きちんと動くようになりました。
#patch-packageの利用
直すことは出来ましたが、node_modulesを直接いじり、
node_modulesごとHerokuへデプロイするのは色々な面で問題がある実装なので
patch-package moduleをインポートして利用することに
(node_moduleを手動で変更している時点で本来良くないですが・・・)
詳しくは参考文献をご覧ください。
#参考文献
なんとなく CORS がわかる...はもう終わりにする。
Swagger x Heroku で手軽に API モック&ドキュメントを作る
かゆいところに手が届く!patch-packageでnpmパッケージを乗りこなそう