오늘 하루종일 swagger를 찾아보다가 드는 의문이, swagger.yaml을 생성하고 그 파일을 바탕으로 nodejs, spring, go framework에 맞는 코드를 생성하면 뭐하지? 내가 그 안을 채웠을때 swagger.yaml과 어떻게 sync를 맞출까... 매번 swagger.yaml을 기준으로 수정하고 다시 코드를 생성하는걸까...? 뭐가 맞는지 정말 모르겠다. Springboot의 경우 annotation을 작성해서 자동으로 swagger.yaml을 만드는데 코드 -> swagger.yaml을 생성이 맞는게 아닐까? swagger.yaml의 역할이 blueprint의 역할을 한다면 swager.yaml에서 코드를 만드는게 맞는것 같기도하고..

뭐가 맞는지는 모르겠지만 일단 koa-swagger-decorator를 찾았다. decorator는 코드에 decorator를 작성해서 swagger json docs을 자동으로 생성해주는 역할을 한다. 내코드가 swagger json을 생성해주니까, 코드만 수정하면 swagger-ui에 바로 반영이 된다.

$ npm install koa-swagger-decorator

현재 swagger에서는 OpenAPI 3.0까지 지원하던데 해당 코드는 Swagger OpenAPI 2.0을 기준으로 한다. migration이 가능할것 같으니 일단은 그냥 사용해보는걸로.. 위 패키지를 설치하고 다음과 같이 코드를 추가한다.

import { SwaggerRouter } from 'koa-swagger-decorator'

사용성이 구려서 사용안하기로

  • swagger-ui는 client를 구현하는 개발자에게 제공되면 매우 유용하다. postman에 APIs를 사전에 저장하고 불러올수있지만 문서화가 되진 않는다.
  • swagger-ui-github에서 다운이 가능하다.
  • swagger UI 버전에따라 OpenAPI Spec compatibility가 정해진다 3.18.3을 살펴보면 OpenAPI 3.0이 가능하다.
  • swagger-ui는 3가지를 제공하는데
    • swagger-ui
    • swagger-ui-dist
    • swagger-ui-react
  • 이중에 강력하게 swagger-ui를 추천한다고 한다. swagger-ui-dist는 single-page application을 개발할때 상당히 크기 때문에
  • swagger-uiswagger-editor를 설치하고 generateServer를 해서 코드를 생성했다면 추가로 설치할 필요가 없다.
    • swagger-editor로 생성된 코드의 프로젝트는 다음 github을 확인
  • http://localhost:8080/docs/
  • 위 코드 clone하고 실행하면 http://localhost:8080/docs/ 에 접속하면

  • Swagger Editor는 말그대로 OpenAPI를 온라인을 통해 작성하는 Editor이다. Swagger Editor는 cloud에서 작업을 할 수 있고,Swagger Editor를 다운받아서 사용이 가능하다. swagger editor
  • swagger-editor-github에서 다운받아서 사용이 가능
  • Docker로 제공하니 감사 swagger-editor#docker
docker pull swaggerapi/swagger-editor
docker run -d -p 80:8080 swaggerapi/swagger-editor
  • http://localhost:80에 들어가면 swagger Editor가 동작한다!

  • swagger 2.0openapi 3.0.1의 Editor를 제공하니 변경해서 사용이 가능

  • Swagger Editor에서 Generate Client에서 javascript코드를 생성하면 아래와 같이 프로젝트가 생성된다.

swagger에 대한 설치 및 이슈에 대해서 정리를 했었는데, 생각보다 쉽지 않은것 같다. swagger의 서버를 별도로 띄워서 사용하는게 이상한것 같고.. (별도의 서버가 있는데) 역시 공홈에 있는 문서를 읽는게 좋은것 같아서 이제는 공홈으로 왔다.

https://swagger.io/

swagger의 공홈을와서 Tools를 보면 총 3가지를 제공한다

  • Swagger Codegen
  • Swagger Editor
  • Swagger Ui

swagger를 하나 떡! 설치하면 모든게 해결되는게 아니라는 사실을 여기서 느꼈다. 각각의 tool에 대해서 알아볼 필요가 있다고 생각한다. postman과 같이 APIs를 정리해놓을수 있지만, APIs의 서버를 만드는이상 APIs의 문서화는 필수라고 생각 (배보다 배꼽이 더 커보이지만 일단은 시작을 해보는게 좋을것 같아서! 아니면 지금 알아놓고 아니다 싶으면 다음에 하면 되니까!)

Swagger Codegen

  • server stubs client SDKs를 생성할수 있게 해준다.
  • 한마디로 OpenAPI(swagger에서 정의한)를 생성해놓고 개발팀은 그에 맞는 포맷으로 개발에 포커싱이 가능하다.
  • 여기서 Available Clients, Avaliable Servers에 대해 나와있는데 각각의 프로젝트에서는 Codegen이 가능하다는 말!
  • 약간 google protobuf와 같은 느낌같다 지금까지는... proto같이 파일을 정의하고 읽고, 쓰는 코드를 생성해주는?
  • 일단 nodejs-server와 javascript가 가능하니 (현재 nodejs와 react를 사용할 예정이니)
  • cloud에서도 제공을 하는데, SwaggerHub의 경우 14일만 사용이 가능하고 그 이후에는 유료버전으로 변경된다. (unlock이 그 의미가 맞겠지요)

  • 처음 시작하면 Create a New API, Import an API가 있다.
  • 들어가보면 특정 사용자들이 데모로 생성한 APIs도 확인이 가능하다. (그냥 데모 테스트할때 사용하면 좋을듯?)

  • 정말 신세계구나... 이렇게 API를 만들어서.
  • Template에는 Oauth 2.0, Simple 등등이 있음
  • 참고로 public이 아니고 private으로 하면 계정을 upgrade 해야한다 (돈을 내라는거지)

  • 이렇게 API가 어떤게 있고, Editor가 있다... 참 신기하다 이런게 있단.

  • 이렇게 생성되고 나면 오른쪽 위에 Export가 있는데 여기서 이제 Client SDK, Server Stub을 자동으로 생성해준다.!!! Postman에서도 API를 호출하는 코드 생성도 너무 편리하게 사용했는데 여기서는 Server Stub까지 생성해주는구나..
  • 참고로 Document를 다운받으면 html의 파일로 APIs 문서를 생성해준다.
  • 실제로 Client SDK를 다운받으려 하는데 javascript는 없는데?
  • 찾아보니 swagger-codegen generate의 CLI로 javascript코드 생성이 가능하다.
swagger-codegen generate \
  --input-spec http://petstore.swagger.io/v2/swagger.json \
  --lang javascript \
  --output . \
  --template-dir ./modules/swagger-codegen/src/main/resources/Javascript/es6 \
  --additional-properties usePromises=true,useES6=true

swagger-codegen-github

  • 훌륭하게도 swagger-codegenopensource이다. 설치해서 사용하면 위에 호스팅을 자신의 서버에서 실행이 가능하다.
  • 현재 버전 2.x와 3.x를 제공하는데 다른 브랜치에서 제공하니 원하는 버전을 사용하면 될것 같음
  • 다른 패키지 설치 할필요없이 docker를 이용하자 code-gen-docker
  • /gen/out아래 output이 생성
git clone https://github.com/swagger-api/swagger-codegen
cd swagger-codegen
./run-in-docker.sh mvn package


./run-in-docker.sh help # Executes 'help' command for swagger-codegen-cli
./run-in-docker.sh langs # Executes 'langs' command for swagger-codegen-cli
./run-in-docker.sh /gen/bin/go-petstore.sh  # Builds the Go client
./run-in-docker.sh generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml \
    -l go -o /gen/out/go-petstore -DpackageName=petstore # generates go client, outputs locally to ./out/go-petstore 
  • 참고로 이렇게 설치하면 cli 툴만 설치했음, Hub에서 있었던 Editor는 따로 설치해야 한다.

swagger-ui-github

설치 #

  • swagger-ui, swagger-ui-dist를 npm을 통해 제공을 한다.
  • $ npm install swagger-ui-dist로 설치
  • $ npm install swagger-ui를 설치
  • Note: we suggest using swagger-ui when your tooling makes it possible, as swagger-ui-dist will result in more code going across the wire.

swagger-ui

  • npm으로 설치하면 node_modules/swagger-ui/dist폴더에 html의 파일이 저장되서 routing만 하면 된다.
import SwaggerUI from 'swagger-ui'
// or use require, if you prefer
const SwaggerUI = require('swagger-ui')
SwaggerUI({
  dom_id: '#myDomId'
})
  • 근데 이해가... 이게 어떻게 동작하지..
Project restarted. Files changed:  [ '/Users/direcision/Desktop/ToyProjects/web/server/swagger/app.js' ]
/Users/direcision/Desktop/ToyProjects/web/server/swagger/node_modules/swagger-ui/dist/swagger-ui.js:1
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SwaggerUICore=t():e.SwaggerUICore=t()}(window,function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){retu

ReferenceError: window is not defined
    at Object.<anonymous> (/Users/direcision/Desktop/ToyProjects/web/server/swagger/node_modules/swagger-ui/dist/swagger-ui.js:1:208)
    at Module._compile (internal/modules/cjs/loader.js:955:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Module.require (internal/modules/cjs/loader.js:848:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/Users/direcision/Desktop/ToyProjects/web/server/swagger/app.js:6:19)
    at Module._compile (internal/modules/cjs/loader.js:955:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
  • 이런 에러가 뜨는데.. 음

swagger-ui-dist

  • swagger-ui-dist를 설치하면 아래와 같이 코드만 추가하면 바로 사용이 가능
const express = require('express')
const pathToSwaggerUi = require('swagger-ui-dist').absolutePath()

const app = express()

app.use(express.static(pathToSwaggerUi))

app.listen(3000)

swagger-ui-express #

  • swagger-ui-express를 설치하면 swagger-ui를 express를 통해서.. 가능하구나
    $ npm install swagger-ui-express
    $ npm install swagger-jsdoc
const swaggerJSDoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');


// Swagger definition
// You can set every attribute except paths and swagger
// https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md
const swaggerDefinition = {
  info: { // API informations (required)
    title: 'Auth Service', // Title (required)
    version: '1.0.0', // Version (required)
    description: 'Auth API' // Description (optional)
  },
  host: 'localhost:3000', // Host (optional)
  basePath: '/' // Base path (optional)
};

// Options for the swagger docs
const options = {
  // Import swaggerDefinitions
  swaggerDefinition,
  // Path to the API docs
  apis: ['./routes/index.js', './users/index.js', './roles/index.js']
};

// Initialize swagger-jsdoc -> returns validated swagger spec in json format
const swaggerSpec = swaggerJSDoc(options);

const app = express();
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));

그 외

+ Recent posts