일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 객체의키값만 찾기
- indexOf()
- ...점점점문법
- 제로베이스
- 중복 문자열
- 중복된 단어
- 재귀스왑
- 문자열 중복
- @Moditying @Query
- sql like연산자
- js 문자열을 문자배열로
- lastIndexOf()
- 배엘에서 스왑
- 단어 제거
- 문자열순서바꾸기
- 레디스 확인
- 스프링 데이타 JPA
- 객체를 배열로
- ubuntu타임존
- 배열을 객체로
- 객체의 밸류값만 찾기
- 중복단어제거
- sql 문자열 패턴 검색
- 코딩 어?
- 깃 토큰 만료
- 우분투 시간 변경
- 중복문자제거
- 시퀄 문법
- 5.3.8 Modifying Queries
- 프론트엔드 스쿨
- Today
- Total
코딩기록
항해 87일) nodejs swagger(json). API 문서관리 본문
swagger에 한,, 하루 반 소요된거 같다. 스웨거만 붙든건 아니었지만
url설정에 문제가 있었지만 해결되었고 yaml방식은 직접 .yaml파일에 적어야하지만 json은 자동으로 생성되고 몇가지만 수정하는 방식이여서 json으로 했다. yaml도 자동으로 틀을 만들어줄거 같은데 아직 못찾았다.
swagger도 2.0버전과 3.0.0버전이 있는데 나는 2.0버전이다.
1. 모듈 설치
$ npm install swagger-ui-express
$ npm install swagger-autogen
2. 파일구조
여기서 app.js, swagger.js, swagger-output.json, models>index.js, .env 파일이 사용된다.
app.js
//상단에 위치
//스웨거 자동생성을 위한 코드
const swaggerUi = require("swagger-ui-express");
// //스웨거 아웃풋파일 저장 위치
const swaggerFile = require("./swagger-output.json");
//하단에 위치
// path설정 /swagger
app.use("/swagger", swaggerUi.serve, swaggerUi.setup(swaggerFile));
swagger.js
const swaggerAutogen = require("swagger-autogen")();
const doc = {
info: {
title: "omogjomog",
description: "omogjomog API",
},
//로컬 테스트
// host: "localhost:3000",
//ec2 인스턴스 주소
host: "13.125.238.144",
schemes: ["http"],
};
const outputFile = "./swagger-output.json";
const endpointsFiles = ["./app.js"];
swaggerAutogen(outputFile, endpointsFiles, doc);
//swaggerAutogen으로 outputfile 파일을 app.js 루트로 api 들을 생성한다.
//이때 명령어는 터미널에서 node swagger.js
//명령어까지 입력하면 swagger-output.json파일이 생성된다.
//package.json에 "prestart": "node ./swagger.js" 설정하면 명령어는 npm start
명령어까지 입력하면 swagger-output.json파일이 생성된다.
보통app.js안에
const port = 3000;
이라고 포트를 쓰지만 나는 dotenv에 비번등 중요한걸 숨겨놨다. 그래서 로컬에서 테스트 할때 models>index.js는
아래와 같이 쓴다.
models > index.js
const mongoose = require('mongoose');
const connect = () => {
mongoose
.connect('mongodb://localhost:27017/Omok', {
ignoreUndefined: true,
})
.catch((error) => {
console.error(error);
});
};
module.exports = connect;
.env
PORT=3000
MONGO_URL='mongodb://test:test@localhost:27017/Omok'
Algorithm='sha512'
TOKENKEY='my-secret-key'
DSN='https://f4d277bb0bba4288b76e4171b4cbcc54@o1188771.ingest.sentry.io/6308910'
여기까지 작성하고 vscode터이널에서 node ./swagger.js 명령어를 치면 swagger-output.json 파일이 생성된다.
이파일은 프로젝트의 코드를 기초로 틀만 생성되는건데 이안에 추가로 내 프로젝트에 맞게 설명을 적으면된다.
"tags": ["user"] 는 api 문서를 보기 편하게 분류 해준다.
"summary": "회원가입" 은 API문서에서 볼수있는 짧은 설명이다.
properties안에 id, pass등 reqest가 있고 example에 실제로 브라우저에서 고객이 입력하는 형식을 적는다.
"example": "user1" 처럼 쓰면 된다.
swagger-output.json
{
"swagger": "2.0",
"info": {
"title": "omogjomog",
"description": "omogjomog API",
"version": "1.0.0"
},
"host": "13.125.229.125",
"contact": {
"git": "https://github.com/Omok-BE/Omok-BE"
},
"basePath": "/",
"schemes": [
"https"
],
"paths": {
"/signup": {
"post": {
"tags": ["user"],
"description": "회원가입",
"summary": "회원가입",
"parameters": [
{
"name": "users",
"in": "body",
"schema": {
"type": "object",
"properties": {
"id": {
"example": "user1"
},
"email": {
"example": "user1@naver.com"
},
"pass": {
"example": "user1"
},
"confirmPass": {
"example": "user1"
},
"profileImage": {
"example": ".svg"
}
}
}
}
],
"responses": {
"201": {
"description": "Created"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/login": {
"post": {
"tags": ["user"],
"description": "로그인",
"summary": "로그인",
"parameters": [
{
"name": "login",
"in": "body",
"schema": {
"type": "object",
"properties": {
"id": {
"example": "user1"
},
"pass": {
"example": "user1"
}
}
}
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
},
"401": {
"description": "Unauthorized"
}
}
}
},
"/findpass": {
"post": {
"tags": ["user"],
"description": "비밀번호 찾기 [유저 확인]",
"summary": "비밀번호 찾기[유저 확인]",
"parameters": [
{
"name": "find",
"in": "body",
"schema": {
"type": "object",
"properties": {
"id": {
"example": "user1"
},
"email": {
"example": "user1@naver.com"
}
}
}
}
],
"responses": {
"201": {
"description": "Created"
},
"400": {
"description": "Bad Request"
},
"401": {
"description": "Unauthorized"
}
}
}
},
"/newpass": {
"post": {
"tags": ["user"],
"description": "비밀번호 찾기 [새 비밀번호 입력]",
"summary": "비밀번호 찾기 [새 비밀번호 입력]",
"parameters": [
{
"name": "newpass",
"in": "body",
"schema": {
"type": "object",
"properties": {
"id": {
"example": "user1"
},
"email": {
"example": "user1@naver.com"
},
"newPass": {
"example": "any"
}
}
}
}
],
"responses": {
"201": {
"description": "Created"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/userinfo/{id}": {
"get": {
"tags": ["user"],
"description": "로그인 체크",
"summary": "로그인 체크",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized"
}
}
}
},
"/lobby": {
"get": {
"tags": ["lobby"],
"description": "로비첫 화면",
"summary": "로비첫 화면",
"parameters": [],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized"
}
}
}
},
"/lobby/userList/{id}": {
"get": {
"tags": ["lobby"],
"description": "로비에서 offline제외 유저리스트",
"summary": "로비에서 offline제외 유저리스트",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized"
}
}
}
},
"/lobby/leaderList": {
"get": {
"tags": ["lobby"],
"description": "로비에서 포인트기준 리더리스트",
"summary": "로비에서 포인트기준 리더리스트",
"parameters": [],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized"
}
}
}
},
"/leaderBoard": {
"get": {
"tags": ["lobby"],
"description": "리더보드: 로비 순위표",
"summary": "리더보드: 로비 순위표",
"parameters": [],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized"
}
}
}
},
"/lobby/create": {
"post": {
"tags": ["lobby"],
"description": "게임방 생성",
"summary": "로비에서 게임방 생성",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"roomName": {
"example": "1"
},
"id": {
"example": "user1"
},
"timer": {
"example": "5 : 00"
},
"boardColor": {
"example": "1"
}
}
}
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized"
}
}
}
},
"/lobby/joinroom/{roomNum}": {
"get": {
"tags": ["lobby"],
"description": "방 참가: 모달창뜰때",
"summary": "방 참가: 모달창뜰때",
"parameters": [
{
"name": "roomNum",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized"
}
}
}
},
"/lobby/joinroom": {
"post": {
"tags": ["lobby"],
"description": "방 참가: 모달창 입력",
"summary": "방 참가: 모달창 입력",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"roomNum": {
"example": "1"
},
"id": {
"example": "user1"
},
"state": {
"example": "inRoom"
}
}
}
}
],
"responses": {
"201": {
"description": "Created"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/lobby/fastPlayer/{id}": {
"get": {
"tags": ["lobby"],
"description": "빠른 참가(플레이어)",
"summary": "빠른 참가(플레이어)",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"201": {
"description": "Created"
},
"400": {
"description": "Bad Request"
},
"401": {
"description": "Unauthorized"
}
}
}
},
"/lobby/fastObserver/{id}": {
"get": {
"tags": ["lobby"],
"description": "빠른 참가(관전자)",
"summary": "빠른 참가(관전자)",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"201": {
"description": "Created"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/lobby/roomNumJoin": {
"post": {
"tags": ["lobby"],
"description": "방번호 참가",
"summary": "방번호 참가",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"id": {
"example": "user1"
},
"roomNum": {
"example": "1"
}
}
}
}
],
"responses": {
"201": {
"description": "Created"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/lobby/logout": {
"post": {
"tags": ["lobby"],
"description": "로그아웃",
"summary": "로그아웃",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"id": {
"example": "any"
}
}
}
}
],
"responses": {
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
}
}
}
},
"/game/create": {
"post": {
"tags": ["game"],
"description": "대기실 => 게임방 입장시 게임방 생성",
"summary": "대기실 => 게임방 입장시 게임방 생성",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"roomNum": {
"example": "1"
},
"blackTeamPlayer": {
"example": "user1"
},
"blackTeamObserver": {
"example": "user2"
},
"whiteTeamPlayer": {
"example": "user3"
},
"whiteTeamObserver": {
"example": "user4"
}
}
}
}
],
"responses": {
"201": {
"description": "Created"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/game/start/{gameNum}": {
"get": {
"tags": ["game"],
"description": "게임방 입장해서 정보가져오기",
"summary": "게임방 입장해서 정보가져오기",
"parameters": [
{
"name": "gameNum",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/game/bugreport": {
"post": {
"tags": ["game"],
"description": "[버그리폿]",
"summary": "[버그리폿]",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"input": {
"example": "text 설명"
},
"gameNum": {
"example": "1"
},
"gameInfo": {
"example": "[{ 'gameNum': 1, 'gameName':'게임ㄱㄱ', 'blackTeamPlayer': 'user1', 'blackTeamObserver': 'user2', 'whiteTeamPlayer': 'user3', 'whiteTeamObserver': 'user4', 'timer': '3 : 00' }]"
},
"userInfo": {
"example": "{ 'id': 'user1', 'state': 'whitePlayer', 'score': {'win':1, 'lose':0}, 'point': 1000, 'profileImage': ' .svg' }"
}
}
}
}
],
"responses": {
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
}
}
}
},
"/gameFinish": {
"post": {
"tags": ["game"],
"description": "[결과창]:게임이 끝나면 바로 보내는 내용",
"summary": "[결과창]:게임이 끝나면 바로 보내는 내용",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"userInfo": {
"example": "{ 'id': 'user1', 'state': 'whitePlayer', 'score': {'win':1, 'lose':0}, 'point': 1000, 'profileImage': ' .svg' }"
},
"gameNum": {
"example": "1"
},
"result": {
"example": "{'win': 'user1', 'state': 'whitePlayer'}"
}
}
}
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/gameFinish/show": {
"post": {
"tags": ["game"],
"description": "[결과창]:페이지로 들어가자마자",
"summary": "[결과창]:페이지로 들어가자마자",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"id": {
"example": "user1"
},
"gameNum": {
"example": "1"
},
"result": {
"example": "{ 'win': 'user1', 'state': 'whitePlayer' }"
}
}
}
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/game/delete/{gameNum}": {
"delete": {
"tags": ["game"],
"description": "방에서 나가기",
"summary": "방에서 나가기",
"parameters": [
{
"name": "gameNum",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/admin/login": {
"post": {
"tags": ["admin"],
"description": "관리자 로그인",
"summary": "관리자 로그인",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"id": {
"example": "admin"
},
"pass": {
"example": "pass"
}
}
}
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
},
"403": {
"description": "Forbidden"
}
}
}
},
"/admin/waitingRoom/list": {
"get": {
"tags": ["admin"],
"description": "대기방 리스트 불러오기",
"summary": "대기방 리스트 불러오기",
"parameters": [],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/admin/waitingRoom/delete/{roomNum}": {
"delete": {
"tags": ["admin"],
"description": "대기방 삭제",
"summary": "대기방 삭제",
"parameters": [
{
"name": "roomNum",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/admin/gameRoom/list": {
"get": {
"tags": ["admin"],
"description": "게임방 리스트 불러오기",
"summary": "게임방 리스트 불러오기",
"parameters": [],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/admin/gameRoom/delete/{gameNum}": {
"delete": {
"tags": ["admin"],
"description": "게임방 삭제",
"summary": "게임방 삭제",
"parameters": [
{
"name": "gameNum",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/admin/users/list": {
"get": {
"tags": ["admin"],
"description": "유저 리스트 불러오기",
"summary": "유저 리스트 불러오기",
"parameters": [],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/admin/users/editPoint/{id}": {
"put": {
"tags": ["admin"],
"description": "유저 포인트 수정하기",
"summary": "유저 포인트 수정하기",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"point": {
"example": 1000
}
}
}
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
}
}
}
},
"/admin/users/delete/{id}": {
"delete": {
"tags": ["admin"],
"description": "유저 삭제하기",
"summary": "유저 삭제하기",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request"
}
}
}
}
}
}
여기까지 하고 vscode 터미널에 node server.js 명령어를 적으면 서버가 돌아간다
그럼 브라우저에 주소를 입력하면 아래와 같은 화면이 뜬다.(ec2 인스턴스 주소)
로컬 주소- localhost:3000/swagger
ec2 인스턴스 주소- http://13.125.229.25/swagger
API문서 테스트 이미지
1. 오른쪽 상단 Try it out 클릭
2. Object { body } 안 내용 작성
내가 적은 swagger-output.json 내용이 그대로 나와서 필요한 부분만 수정하면된다.
파랑색 Execute 버튼을 누른다.
3. 성공하면 아래 201이 뜨고
실패하면 아래와 같이 오류 메시지가 뜬다. 회원가입 API 테스트를 했고 2가지 실패 상황이 발생했다.
1-1. 400 에러 (설정한 에러)
비밀번호 2번 입력하는데 비밀번호 확인에서 다른 비밀번호를 입력했다.
1-2. 400 에러 (설정한 에러)
2. cors 에러가 났고 app.js에서 cors관련해서 확인하면 된다.
'항해99 > 챕터6 실전 프로젝트' 카테고리의 다른 글
항해 78일) 실전 프로젝트 - 오목 1차 배포 및 피드백 (0) | 2022.03.31 |
---|---|
항해 81일) 항해 5기 프로젝트 모음 (0) | 2022.03.31 |
항해 64일) ubuntu 시간 Seoul로 설정하기 (0) | 2022.03.14 |
항해 61일) 코딩 변수명 표기방법- 카멜케이스, 파스칼케이스, 스네이크케이스, 케밥케이스 (0) | 2022.03.11 |