LoginSignup
2
2

More than 3 years have passed since last update.

Swagger EditorのGenerate Serverで生成したNode.js serverのcors問題を解消した話

Last updated at Posted at 2021-01-14

備忘録代わりとして書きます。
間違い、より楽なやり方もあると思いますのでご指摘大歓迎です。

概要

openapi3.0でYAMLファイルを書き、
Swagger EditorのGenerate Server機能を用いてNode.jsを自動生成し、
HerokuへデプロイしてMock Serverにしようとしました。

やり方

Mock Serverコードを記述したらGenerate Server > nodejs-serverを選択し、サーバコードをダウンロードする。
https___qiita-image-store.s3.amazonaws.com_0_19698_498beaf3-8a46-a99b-0db2-c3741602b8f2.png

ダウンロードしたNode.jsを解凍し、index.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をインポート

./node_modules/oas3-tools/dist/middleware/express.app.config.js

'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パッケージを乗りこなそう

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2