Skip to content

[Web for Untact DriveThru] Express와 Rest Api를 사용하여 라우팅하기

kiJiyeon edited this page Jan 20, 2021 · 1 revision

Rest API

서버 데이터를 구조적으로 사용하기 위한 API 디자인을 REST API라고 한다.

  • Method는 주로 GET과 POST만 사용한다.
GET - 조회하다
POST - 생성하다
PUT - 갱신하다
DELETE - 삭제하다

Rest API(REpresentational State Transfer) for HTTP request

  • 웹상에서 사용되는 여러 리소스를 HTTP URI로 표현하고, 그 리소스에 대한 행위를 HTTP Method로 정의하는 방식이다.

  • 리소스(HTTP URI로 정의된)를 어떻게 한다(HTTP Method + Payload)를 구조적으로 깔끔하게 표현하는 것이다.

RESTful HTTP API 구조 및 핵심 개념

  • URI(Uniform Resource Identifier)

    해당 사이트의 특정 자원의 위치를 나타내는 유일한 주소 (ex. /login, /news)

  • HTTP Method

    HTTP Request가 의도하는 action을 정의 (ex. POST, GET 등..)

  • Payload

    HTTP Request에서 보내는 데이터 (body)

About function - Fetch()

Fetch

fetch함수는 API를 사용하여 백엔드 서버와 비동기 요청을 하는 방식 중 하나이다.

  • method

method는 GET POST DELETE 등이 있는데, GET은 어떠한 정보를 가져올 때, POST는 어떠한 정보를 백에 보낼 때, DELETE는 단어 그대로 삭제할 때 사용한다. 메서드의 디폴트값은 GET이기 때문에 아무런 정보를 적지 않으면 GET으로 적용된다.

  • headers

API 응답에 대한 헤더정보를 담고있다.

  • body

전달하고자 하는 응답 내용이다. 백과 통신할 때는 객체로 통신하기 때문에 객체타입으로 작성해야한다.

method, headers, body는 전달하고자하는 정보에 대한 정보이기 때문에 정보를 가져올 때, 즉 GET하는 경우에는 작성해줄 필요는 없다.

fetch('http://localhost:4000/getData')
    .then(response => 
      response.text()
    )
    .then(data => {
      console.log(JSON.parse(data));
      this.setState({username: data});
    });

.then 함수

자바스크립트에서 함수는 동기함수, 비동기함수로 나뉜다. 우리가 작성한 코드들은 위에서부터 아래로 순차적으로 코드가 실행되고 하나의 코드가 종료되지않는다면 다음 코드로 넘어가지 않는다. 이것이 동기함수이다. API를 호출할 때, 사용하는 fetch 함수는 대표적인 비동기함수이다. 그렇기때문에 API호출하는 과정이 끝나지 않더라도 자동적으로 다음 코드로 넘어간다. 하지만 API로부터 받아온 정보를 사용할 필요가 있는 경우에 .then함수를 쓰는 것이다!

then을 쓰면 그 뒤에 있는 내용들, 위의 코드에서는

(response => 
      response.text()
    )
(data => {
      console.log(JSON.parse(data));
      this.setState({username: data});
    })

두 부분이 서버응답이 끝나면 실행된다.

React에 Express연결하기

create-react-app으로 React프로젝트를 생성한 후,명령프롬프트 창에서 다음과 같이 입력한다.

cd [root 폴더위치]

yarn eject

yarn eject를 하는 이유는, React프로젝트를 생성 할 때 같이 설치되는 여러 모듈 중 Webpack관련 설정이 나중에 필요하기 때문에 숨어있는 폴더를 끄집어 내기 위함이다!

그다음

yarn add express

를 입력하여 Express모듈을 설치한 후,

1. 루트 폴더/src위치에 server폴더를 생성하고, 그 안에 server.js파일을 생성하고 다음과 같이 작성한다.

<server.js>

const express = require('express');
const path = require('path');
const os = require("os");

const app = express();
const PORT = process.env.PORT || 4000;

app.use(express.static('public'));

app.get("/signIn",cors(), function(req, res){
  res.send({ username: os.userInfo().username }); 
  //localhost:4000/signIn에서 get해오는 것 예시로 넣은것
  });

app.listen(PORT, () => {
  console.log(`check :${PORT}`);
});

Express서버의 라우팅 설정 및 DB연결하기

1. server폴더 안에 dbConnection.js 파일을 생성하고 다음과 같이 작성한다.

connection 객체에 포함 되는 요소들은 다음을 참고해서 작성하면 된다!

(본 프로젝트에서는 Azure를 사용하여 서버를 구축하였으므로 Azure중심적으로 설명한다.)

const mysql = require('mysql');
const connection = mysql.createPool({
    host: 'yellow-postit.mysql.database.azure.com',
    user: 'theSecretChamber@yellow-postit',
    password: 'Jeonha12#',
    database: 'untact_drivethru_db',
    port: 3306,
    ssl: false
})

module.exports = connection;
  • host: 연결하고자 하는 서버의 주소, 사진의 서버 이름(예제 코드에서는 작성자의 Azure DB서버의 주소이다.)
  • user: 서버 관리자 로그인 이름
  • password: database server for mysql을 생성할 때 만든 비밀번호
  • database: 사용할 데이터베이스 이름으로, *mysql workbench에서 미리 만들어 두어야한다.
  • port: 호스트와 연결할 때 사용할 port번호, 일반적으로 3306번을 사용한다.
  • ssl: false로 지정한다.

SSL을 false로 사용하는 이유는?

ssl을 disable, 즉 ssl을 사용하지 않아야 나중에 애플리케이션이 데이터베이스에 접속할 때 문제가 발생하지 않는다.

SSL 이란?

우리가 접속하는 웹 브라우저와 서버간 암호화 통신을 하게 해주는 인증서로, 웹 상에서 고객이 입력한 정보가 웹 서버로 이동하는 구간을 암호화 해서 전달함으로써 중간에 정보를 가로채는 공격을막아 주는 역할을 한다.

  • 통신 내용이 공격자에게 노출되는 것을 막을 수 있다.
  • 클라이언트가 접속하려는 서버가 신뢰 할 수 있는 서버인지를 판단할 수 있다.
  • 통신 내용의 악의적인 변경을 방지할 수 있다.

2. server폴더 안에 routes 폴더를 생성한 후, router.js파일을 생성하고 다음과 같이 작성한다.

<router.js>

const { res } = require('express');
const express = require('express');
const { req } = require('http');
const os = require('os');
const router = express.Router();
const db = require('../dbconnection');
const cors = require('cors');


router.get('/signIn', cors(), (req, res) => {
    
    db.query("select UserWebId, PW from usertable;", (err, rows) => {
        if(!err) {
            console.log(rows);
            res.send(rows);
        } else {
            console.log(`query error: ${err}}`);

            res.send(err);
        }
    })
})

module.exports = router;

여기서, router.get('/signIn',cors(),(req,res))=>{ ... }는, URL의 뒷부분이/signIn인 경로(예를들면, http://localhost:4000/signIn)에 있는 api에서 정보를 요청하고 그 응답을 받아오는 기능을 한다.

get을 사용했기 때문에, api의 정보를 읽어오는 것만 가능하다.

위에서 설명했듯이, REST API의 Client요청에는 Get, Post, Delete, Put이 있는데, 이 중 우리는 GetPost만을 사용할 것이다!


fetch()함수를 사용하여router.js에 정의한 것들을 실행시킬 수 있다.

예제에서는 다음과 같이 사용하였다.

<app.js>

import React, {Component} from 'react'; 
import './App.css';

class App extends Component {
  state = {username: null};

  componentDidMount() {
    fetch('http://localhost:4000/signIn')
    .then(response => 
      response.text()
    )
    .then(data => {
      console.log(JSON.parse(data));
      this.setState({username: data});
    });
  }

  render() {
    const username = this.state.username;

    return (
        <div>
          <h1>{username}</h1>
        </div>
      
      </div>
    )
  }
}

export default App;

위 코드에 대한 설명은 About function - Fetch()파트에 설명해 놓았으니 참고바람!

3. server.js파일을 다음과 같이 수정한다.

<server.js>

const express = require('express');
const path = require('path');
const os = require('os');
const router = require('./routes/router');

const app = express();
const PORT = process.env.PORT||4000;

app.use('/', router);
app.use(express.static('public'));

app.listen(PORT, () => {
    console.log(`check :${PORT}`);
})

server.js에서 PORT를 지정해주었는데, 이 포트는 <dbconnection.js>의 port와 같지 않다는것 주의!!


app.use( ... )는 Express의 라우팅 Method이다.

app.use('/', router);는 URL마지막 부분이 '/'로 끝날 때(예를들면, http://localhost:4000/), 괄호 안에 쓰인 미들웨어인, router를 실행하도록 한다.

*미들웨어란? 클라이언트와 서버 간의 통신을 담당하는 시스템 소프트웨어 또는 컴퓨터와 컴퓨터의 연결을 담당하는 시스템 소프트웨어


app.listen(PORT, ()=>{...})은, 포트에 접속이 성공했을 때, 중괄호 안의 콜백 함수를 실행시키는 역할을 한다.

실행하기

  1. react프로젝트에서 yarn start 또는 npm start

  2. 명령 프롬프트에서 다음과 같이 입력

    cd src\server
    node server.js
    
  3. Azure의 DB서버는 꼭 켜주기

Reference

Rest API

Clone this wiki locally