-
[2019.04.23] API 서버를 만들어보자 - http 방식개발 블로깅/Server&DataBase 개념 2019. 4. 23. 11:22
node.js를 이용한 API를 직접 만들어 볼 기회가 올 줄이야. 정말 내가 원하는 작업이였다...ㅜㅜ (그렇다고 백엔드를 갈구하는 편은 아니다..)
지금부터 API 서버를 만들어 보는 작은 프로젝트를 작업해보자.
프로젝트로 쓸 디렉토리 생성
mkdir serverProject cd serverproject
module 관리자 package.json 생성
npm init -y
서버 개발 중 코드를 작업 후 저장하면 바로 적용되는 nodemon 모듈을 로컬로 설치 (새로고침을 안해도 됨)
npm i -D nodemon
package.json에 nodemon 설정 (npm start 명령어로 바로 실행 시킬 수 있도록 설정)
{ "name": "testServer", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "./node_modules/nodemon/bin/nodemon.js server/runServer.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "nodemon": "^1.18.11" } } // package.json 파일
이제 VSCode를 켜서 서버와 클라이언트로 쓸 파일을 생성한다.
각 파일 정보
- index.html : 서버에게 요청 및 응답받을 클라이언트
- server/runServer.js : 서버를 생성하여 돌릴 파일 (경로 주의)
- server/handle_Server.js : 실제 서버가 요청, 응답에 대한 작업을 처리하는 파일 (경로 주의)
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <input type="text" id='inputText' /> <input type="button" id="btn" value="go" onclick="test()" /> <input type="text" id='resultText' /> <script> function test(){ var input = document.getElementById('inputText').value; } </script> </body> </html>
클라이언트는 최대한 간결하게 만들었다.
왼쪽 인풋박스는 서버에 요청 값을 보낼 박스, 오른쪽 input은 응답받아서 표시할 박스이다.
# server/runServer.js
const http = require('http'); // node에 내장된 http 모듈 const handle = require('./handle_Server'); // 실제 요청, 응답 작업을 처리할 파일 const port = 3000; // 서버 요청 포트 const ip = '127.0.0.1'; // 서버 ip const server = http.createServer(handle); // 서버 생성 server.listen(port, ip); // 서버 접속경로 설정
서버를 생성해주는 부분이다. 서버를 직접 작업하는 파일을 따로 분리시켜놔서, require로 받아서 사용한다.
# server/handle_Server.js
const requestHandler = function (request, response){ const headers = defaultCorsHeaders; headers['Content-Type'] = 'text/plain'; // 응답하는 컨텐츠의 자료 타입을, 응답 헤더에 기록 let statusCode = 200; // 200 : 요청 성공, 404: 실패 let responseValue = ''; if(request.method === 'POST'){ }else if(request.method === 'GET'){ }else if(request.method === 'OPTIONS'){ } response.writeHead(statusCode, headers); response.end(JSON.stringify(responseValue)); } const defaultCorsHeaders = { // 요청에 맞는 'access-control-allow-origin': '*', 'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS', 'access-control-allow-headers': 'content-type, accept', 'access-control-max-age': 10 // Seconds. }; module.exports = requestHandler; // 외부에서 사용할 수 있도록 exports
기본적인 세팅이다. 클라이언트에서는 요청 방식이 POST,GET,PUT,DELETE 방식 중 하나를 쓰지만, 일반적으로는 GET,POST를 쓰므로, 이렇게 설정을 해준다.
∴ OPTIONS란? 클라이언트는 서버에게 요청을 보내면 두개의 신호를 보낸다. 하나는 서버에 요청 및 응답이 잘 되는지 테스트 신호인 OPTIONS, 두번째가 실제 클라이언트가 보내고자 하는 방식의 신호를 보낸다.
첫번째 신호인 OPTIONS가 응답 및 요청에 실패를 하면, 두번째 신호는 보내지 않고 바로 요청 실패로 처리한다.
이제 우리는 클라이언트가 소문자 알파벳을 보내면, 서버는 대문자로 변환하여 응답을 보내는 작업을 해보자.
# index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <input type="text" id='inputText' /> <input type="button" id="btn" value="go" onclick="test()" /> <input type="text" id='resultText' /> <script> function test(){ var input = document.getElementById('inputText').value; fetch('http://localhost:3000/upper',{ method: 'POST', body: JSON.stringify(input), headers: { 'content-type': 'text/json' } }) .then(res => {res.json()}) .then(res => {document.getElementById('resultText').value = res;}); } </script> </body> </html>
fetch 서버요청 방식은 앞 단에서 배웠을 것이다. 위 와 같이 입력한 내용을 서버에게 보내는 POST 요청 방식을 한다. (경로에 주의한다.)
서버에게 응답받은 데이터를 오른쪽 input 박스에 넣는 작업을 한다.
# handle_Server.js
클라이언트에게서 데이터를 받는 방식은 아래와 같다.
let body = ''; // 클라이언트가 보낸 데이터를 담을 변수 request.on('data', data => { body += data.toString(); // 버퍼 상태의 데이터를 데이터로 변환(?) });
왜 이렇게 되는지는 모르겠다. 그냥 외워야 한다.
데이터를 클라이언트에게 보내느 방식은 아래와 가다.
request.on('end', () => { response.writeHead('200', headers); response.end('보낼 데이터'); }
그럼 위 방식을 이용해서 handle_Server.js 파일을 적절히 작업해보자. 조금 복잡할 수 있다...
const requestHandler = function (request, response){ const headers = defaultCorsHeaders; headers['Content-Type'] = 'text/plain'; // 응답하는 컨텐츠의 자료 타입을, 응답 헤더에 기록 let statusCode = 200; // 200 : 요청 성공, 404: 실패 let responseValue = ''; if(request.method === 'POST'){ let body = ''; // 클라이언트가 보낸 데이터를 담을 변수 request.on('data', data => { body += data.toString(); // 버퍼 상태의 데이터를 데이터로 변환(?) }); // 사실 나도 여기는 잘 모르겠다.. request.on('end', () => { if(request.url === '/upper'){ responseValue = body.toUpperCase(); }else if(request.url ==='/lower'){ // 미구현 } response.writeHead(statusCode, headers); // 응답헤더 설정 response.end(responseValue); // 응답 메세지 전달 및 서버 요청 종료 } ); }else if(request.method === 'GET'){ }else if(request.method === 'OPTIONS'){ response.writeHead(statusCode, headers); response.end('1'); } } const defaultCorsHeaders = { // 요청에 맞는 'access-control-allow-origin': '*', 'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS', 'access-control-allow-headers': 'content-type, accept', 'access-control-max-age': 10 // Seconds. }; module.exports = requestHandler; // 외부에서 사용할 수 있도록 exports
제대로 서버에 요청하고 대문자로 변환된 데이터를 받아오는 것을 확인할 수 있다.
반응형'개발 블로깅 > Server&DataBase 개념' 카테고리의 다른 글
[2019.04.24] 실시간 통신 API - webSocket (0) 2019.04.24 [2019.04.24] API 통신 방식 -express (0) 2019.04.24 [2019.04.23] RESTful API 개념 (0) 2019.04.23 [2019.04.23] node.js에 대해 알아보자 (0) 2019.04.23 [2019.03.26] NoSQL MongoDB 기초 (0) 2019.03.26