글 목차
(1) Node.js로 RESTful API 만들기 - POST편
(2) Node.js로 RESTful API 만들기 - GET편
(3) Node.js로 RESTful API 만들기 - PUT편
(4) Node.js로 RESTful API 만들기 - DELETE편
현재글 >> (5) RESTful API 활용하기 - 웹편
(6) RESTful API 활용하기 - 안드로이드 앱편 (작성중)
이제 앞선 강의에서 만든 API 서버를 가지고 웹에서 요청을 날려볼 것이다.
그러면 우선 웹을 만들어야 한다. 보통은 html을 만들지만, 이 강의에서는 쉽고 빠르게 작성하기 위해 pug 뷰 엔진을 사용하도록 하겠다.
프로젝트가 있는 경로에서 아래 명령어를 이용해 pug를 설치하자.
npm install pug
app.js
그 다음 app.js를 다음과 같이 바꾸어 준다.
자세한 설명은 주석에 있다.
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 29 30 31 32 33 34 35 36 37 38 39 40 41 | var express = require("express"); var mysql = require("mysql"); var bodyParser = require("body-parser"); var config = require("./config"); // config.js var path = require("path"); var pug = require("pug"); var app = express(); // bodyParser는 미들웨어이기 때문에 라우터 보다 항상 위에 있도록 해야함 app.use(bodyParser.json()); // parse application/x-www-form-urlencoded app.use(bodyParser.urlencoded({extended: false})); // 앱의 뷰 엔진을 pug로 설정 app.set("view engine", "pug"); // view 파일 (html) 들이 있는 경로 설정 // 여기서는 ./public/views/~ app.set("views", path.join(__dirname, "public", "views")); // Mysql DB pool 생성 var pool = mysql.createPool({ // config.js에 있는 정보를 바탕으로 연결 host: config.mysql.host, port: config.mysql.port, user: config.mysql.username, password: config.mysql.password, database: config.mysql.db, connectionLimit:20, waitForConnections:false }); // Main app.listen(config.port, function() { console.log("Server listening on port %d", config.port); }); // Router // 기본으로 index.js를 찾기 때문에 // require("./routes/index.js")라고 명시해주지 않았음 var routes = require("./routes")(app, pool); var apiRoutes = require("./routes/api")(app, pool); | cs |
파일 경로
app.js에서 view파일이 ./public/views 경로 아래에 있다고 말해놓았기 때문에
그 경로를 실제로 만들어 주어야 한다.
mkdir public
cd public
mkdir views
cd views
touch index.pug
위의 명령어를 사용하거나 그냥 직접 만들어주면된다.
전체 파일 구조는 아래 사진과 같다.
api.js
api.js? 이상한게 보인다.
api.js는 기존에 있던 index.js를 복사해서 라우트 경로만 /api/를 더 추가해 준 코드다.
index.js는 이제 웹에서 쓸 것들을 모을거고, api는 api.js에 넣어놓았다. 전체 코드는 아래와 같다.
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | var async = require("async"); var mysql = require("mysql"); module.exports = function(app, pool) { // >> POST app.post("/api/games", function(req, res) { var result = {}; var title = null; async.waterfall([ function(callback) { title = mysql.escape(req.body.title); callback(); }, function(callback) { if (title == undefined) { callback(new Error("Title is empty.")); } else { // db에 연결하여 sql 수행 pool.getConnection(function(err, conn) { // title 정보를 DB에 넣기 위한 SQL문 준비 var sql = "INSERT INTO myGames (title) VALUES (" + title + ");"; console.log("SQL: " + sql); conn.query(sql, function(err) { if (err) { // err가 떠도 conn은 release() 꼭 해주어야한다. conn.release(); callback(err); } else { conn.release(); callback(); } }); }); } }], function(err) { result = returnResult(err, res) result.status = res.statusCode; res.send(result); }); }); // >> GET app.get("/api/games", function(req, res) { var result = {}; // db에 연결하여 sql 수행 pool.getConnection(function(err, conn) { var sql = "SELECT * from myGames;"; conn.query(sql, function(err, rows) { var result = returnResult(err, res); if (rows) { result.message = rows; } conn.release(); result.status = res.statusCode; //res.send(result); // games라는 이름으로 결과들을 index.pug로 넘김 res.render("index", { games: rows }); }); }); }); // >> GET/id app.get("/api/games/:id", function(req, res) { var result = {}; // SQL injection attack 방지위해 mysql.escape(); var id = mysql.escape(req.params.id); // db에 연결하여 sql 수행 pool.getConnection(function(err, conn) { var sql = "SELECT * from myGames WHERE id=" + id + ";"; conn.query(sql, function(err, rows) { var result = returnResult(err, res); if (rows) { result.message = rows; } conn.release(); result.status = res.statusCode; res.send(result); }); }); }); // >> PUT app.put("/api/games/:id", function(req, res) { var result = {}; var id = null; var title = null; async.waterfall([ function(callback) { id = mysql.escape(parseInt(req.params.id)); title = mysql.escape(req.body.title); callback(); }, function(callback) { if (id == undefined) { callback(new Error("Id is empty.")); } else if (title == undefined) { callback(new Error("Title is empty.")); } else { // db에 연결하여 sql 수행 pool.getConnection(function(err, conn) { // title 정보를 업데이트 하기 위한 SQL var sql = "UPDATE myGames SET title=" + title + " WHERE id=" + id + ";"; console.log("SQL: " + sql); conn.query(sql, function(err) { if (err) { // err가 떠도 conn은 release() 꼭 해주어야한다. conn.release(); callback(err); } else { conn.release(); callback(); } }); }); } }], function(err) { result = returnResult(err, res) result.status = res.statusCode; res.send(result); }); }); // >> DELETE app.delete("/api/games/:id", function(req, res) { var result = {}; var id = null; async.waterfall([ function(callback) { id = mysql.escape(parseInt(req.params.id)); callback(); }, function(callback) { if (id == undefined) { callback(new Error("Id is empty.")); } else { // db에 연결하여 sql 수행 pool.getConnection(function(err, conn) { var sql = "DELETE FROM myGames WHERE id=" + id + ";"; conn.query(sql, function(err) { if (err) { // err가 떠도 conn은 release() 꼭 해주어야한다. conn.release(); callback(err); } else { conn.release(); callback(); } }); }); } }], function(err) { result = returnResult(err, res) result.status = res.statusCode; res.send(result); }); }); } var returnResult = function(err, res) { // 결과를 눈으로 보기 쉽게하기 위해 result 객체 생성 var result = {}; if (err) { res.status(400); result.message = err.stack; } else { res.status(200); result.message = "Success"; } return result; } | cs |
index.js
index.js에서는 request 라이브러리를 사용해서 api.js 에있는 라우터를 호출 했다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | var request = require("request"); var apiUrl = "http://localhost:3000/api/games" module.exports = function(app, pool) { // >> Index page app.get("/", function(req, res) { // GET 메소드 /games로 넘어감 res.redirect("/games"); }); // >> 게임 목록 (홈) app.get("/games", function(req, res) { request(apiUrl, function (err, response, result) { if (!err && response.statusCode == 200) { // api에서 get으로 받아온 결과를 JSON으로 변환, 메세지만 가져옴 var gameData = JSON.parse(result).message; // games라는 이름으로 결과들을 index.pug로 넘김 res.render("index", { games: gameData }); } }); }); } | cs |
index.pug
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | doctype html html head title 내가 해 본 게임들 // JQuery 사용 script(src="https://code.jquery.com/jquery-3.1.1.min.js") body h3 해본 게임 목록 ul // pug의 반복문 each game in games // 받은 게임 중에서도 title 속성 값만을 뿌린다. li= game.title button(class="button-delete" id="button-delete-" + game.id type="submit") 삭제 form(id="form-change-" + game.id) input(id="input-change-" + game.id type="text") button(class="button-change" id="button-change-" + game.id type="submit") 이름 변경 hr h3 게임 등록 input(id="input-post" type="text") button(id="button-post" type="submit") 등록하기 // 여기서 부터는 script, public/javascript/만들어서 관리 해도됨 script. // PUT 메소드 $(".button-change").click(function() { // id값 가져오기 var game_id = $(this).attr("id").split("-")[2]; var nameToChange = $("#input-change-" + game_id).val(); if (nameToChange.length < 1) { alert("바꿀 이름을 입력하세요."); } else { // 전송할 JSON Data 만들기 var gameData = { "title": nameToChange } $.ajax( { type: "PUT", data: gameData, url: "/api/games/" + game_id, dataType: "JSON" }).done(function(res) { // 성공시 폼 초기화 if (res.status == 200) { $("#input-change-" + game_id).val(""); } else { alert("이름 변경에 실패하였습니다."); } }); } }); // POST 메소드 $("#button-post").click(function() { var title = $("#input-post").val(); if (title.length < 1) { alert("등록할 게임 이름을 입력하세요."); } else { // 전송할 JSON Data 만들기 var gameData = { "title": title } $.ajax( { type: "POST", data: gameData, url: "/api/games/", dataType: "JSON" }).done(function(res) { if (res.status == 200) { // 새로고침 window.location.reload(); } else { alert("게읻 등록에 실패하였습니다."); } }); } }); // Delete 메소드 $(".button-delete").click(function() { var game_id = $(this).attr("id").split("-")[2]; $.ajax( { type: "DELETE", url: "/api/games/" + game_id, }).done(function(res) { if (res.status == 200) { window.location.reload(); } else { alert("게임 삭제에 실패하였습니다."); } }); }); | cs |
여기서 get, put, delete, post 모든 작업을 할 수 있다.
별거 아닌 듯 보였는데 웹을 정말 몰라서 힘든 작업이었다. ㅠㅠ
다음엔 android로 API 서버와 통신을 해 보겠다.
'프로그래밍 > General' 카테고리의 다른 글
구글 검색결과 상단에 내 페이지가 나오는 비결 (1) | 2017.04.15 |
---|---|
[Node.js] PM2에서 NODE_ENV 설정하여 실행하기 (0) | 2017.04.01 |
Git 자주 쓰는 명령어, 이것만 알아두자! (0) | 2017.01.11 |
간단한 정규 표현식 (0) | 2016.12.22 |
HTTP 개관 (0) | 2016.07.25 |