새소식

프론트엔드 공부/Web Server

StatesAirline Server

  • -

1. statesairline

  • statesairline/app.js 는 서비스에 필요한 미들웨어와 웹 서버를 실행하는 코드가 작성되어 있습니다.

2. router

  • statesairline/router/ 안에는 airport API, book API, flight API 요청을 수행하는 라우터가 작성되어 있습니다. 작성된 라우터 내용을 통해 API 요청을 받을 수 있습니다.

3. controller

  • statesairline/controller/ 안에는 정의된 API 요청을 수행하는 코드를 작성해야 합니다. ( airportController.js 에 작성된 내용을 참고하여 작성합니다. )

4. repository

  • statesairline/repository/flightlist.js 는 서비스에서 제공하는 항공편 데이터가 작성되어 있습니다. 이 데이터로 서비스를 구현합니다.
  • statesairline/repository/airportlist.js 는 서비스에서 제공하는 공항 데이터가 작성되어 있습니다.

5.test

  • statesairline/__test__/statesairline.test.js 은 Jest 스펙을 가지고 있으며 코드 테스트를 위한 테스트 케이스가 작성되어 있습니다.
  • npm install 을 통해서 package.json에 설정된 패키지를 설치하세요.
  • npm start를 통해 서버를 실행하세요.
  • Postman으로 API 동작 여부를 확인하세요.
  • npm test를 통해 테스트를 실행하세요.
  • 서버에서 사용되는 포트 번호로 실행되지 않는 경우, 관리자 권한을 부여하여 실행하거나 해당 포트를 사용 중인 프로그램을 종료 후 재시작을 합니다.

Bare Minimum Requirements

  • statesairline/controller/flightController.js와 statesairline/controller/bookController.js 에 코드를 작성하세요.
  • Express 공식문서에서 req.query , req.params를 사용하는 방법을 확인하세요. Query와 Params를 기준으로 데이터를 필터링하는 코드를 작성해야 합니다.
  • 예약 데이터는 controller/bookController.js 안에 작성된 let booking = []; 배열에 저장해야 합니다.
  • Flight API -> 항공편 수정은 Advanced Challenges입니다.

Advanced Challenges

Advanced 콘텐츠의 문제를 해결하려면, 충분한 컨텍스트가 필요할 수 있습니다. Bare minimum requirements 를 완료했다면 도전하세요.

생성한 데이터를 수정할 수 없다면, 매번 데이터를 지우고 다시 생성해야 합니다. 이런 불편을 서비스에서 제거하려면, 데이터를 수정할 수 있는 기능을 추가하면 됩니다.
Advanced 콘텐츠에서는 PUT 요청에 따라 항공편을 수정하는 기능을 구현합니다.

1. 목표

  • Flight API -> 항공편 수정에서 정의한 API 요청을 수행하는 코드를 작성하세요.
  • Advanced Challenges에 있는 모든 테스트를 통과해야 합니다.

2. 참고 내용

  • flight.uuid는 변경되면 안 됩니다.
  • flight JSON의 일부만 수정할 수 있어야 합니다.

과제 시작 전

Express 공식문서에서 req.query , req.params를 사용하는 방법을 확인할 것이다.

req.query

 

Express 4.x - API 참조

Express 4.x API express() Creates an Express application. The express() function is a top-level function exported by the express module. var express = require('express') var app = express() Methods express.json([options]) This middleware is available in Ex

expressjs.com

// localhost:3000/topic?id=1&name=foo
app.get('/topic', function(req, res) {
    res.send(req.query.id + ',' + req.query.name);
})

위 코드는 id과 name 값을 동시에 가져올 수 있다. localhost:3000/topic?id=1&name=foo 에 들어간다고 가정하자. 화면에 1,foo 가 보일 것이다.

// localhost:3000/topic?id=1
app.get('/topic', function(req, res) {
    var topics = [
        'JavaScript is ....',
        'Nodejs is ....',
        'Express is ....',
    ];
    res.send(topics[req,query.id]);
    })

위 코드는 배열로 값들을 가져온다. localhost:3000/topic?id=1 에 들어간다고 가정하면, id가 1이기 때문에 topic[1]인 Nodejs is....가 화면에 보인다.

실제로는 topics에 파일이나 데이터베이스로 교체해서 짧은 코드로 값을 가져올 것이다.

req.params

localhost:3000/page/CSS에 들어간다고 하면 아래와 같은 결과가 나올 것이다.

{"pageId : "CSS"}

req.params안에는 객체가 들어가 있고, 그 객체의 pageId 프로퍼티 값을 통해서 CSS라는 값을 가져온다는 뜻이다.

//localhost:3000/page/CSS/WEB
app.get('page/:pageId/:chaperId', function(req, res) {
    res.send(req.params);
})
{"pageId" : "CSS", "chaperId": "WEB"}

제공된 코드 분석 및 작성코드(Advanced Challenges 까지, 옵션인 코드는 미작성)

app.js (수정 없음)

const express = require('express');
const cors = require('cors');
const app = express();

// 모든 서버는 요청을 받을수 있는 포트 번호를 필요로 합니다.

// HTTP server의 표준 포트는 보통 80 번 이지만, 보통 다른 서버에서 사용중이기 때문에 접근할 수 없습니다.
// 따라서 우리는 보통 테스트 서버 포트로 3000, 8080, 1337 등을 활용합니다.

// PORT는 아파트의 호수와도 같습니다. 서버로 요청을 받기 위해서는 다음과 같이 포트 번호를 설정 합니다.
// (* 때에 따라 다른 포트번호를 열고 싶다면, 환경 변수를 활용 하기도 합니다.)
const port = 3001;

const flightRouter = require('./router/flightRouter');
const bookRouter = require('./router/bookRouter');
const airportRouter = require('./router/airportRouter');

app.use(cors());
app.use(express.json());
//app.use를 통해서 flightRouter, bookRouter, airportRouter에 분기점을 만들어 줌
app.use('/flight', flightRouter);
app.use('/book', bookRouter);
app.use('/airport', airportRouter);
// controller 함수 -> router.js -> app.js 로 불려져서 사용되기 때문에
// flightController.js와 bookController.js 에 코드를 작성해서 
// 항공편과 예약 데이터를 조회, 생성, 수정, 그리고 삭제하는 기능을 구현하면 된다

app.get('/', (req, res) => {
  res.status(200).send('Welcome, States Airline!');
});

app.use((req, res, next) => {
  res.status(404).send('Not Found!');
});

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send({
    message: 'Internal Server Error',
    stacktrace: err.toString()
  });
});

app.listen(port, () => {
  console.log(`[RUN] StatesAirline Server... | http://localhost:${port}`);
});

module.exports = app;

이 코드는 Node.js 기반의 Express 웹 서버를 구축하기 위한 코드입니다. 먼저 포트 번호(port)를 지정합니다. 그 다음, flightRouter, bookRouter, airportRouter 라우터를 app.use() 메소드로 사용하고, '/' URL이 요청 되었을 때 'Welcome, States Airline!'이라고 보내고 404 Not Found! 그리고 500 Internal Server Error의 경우 에-대해 응답합니다. 그 다음 app.listen() 메소드를 통해 port 3000을 listen합니다.

airportController.js  (수정 없음)

const airports = require('../repository/airportList');

module.exports = {
  // [GET] /airport?query={query} 요청을 수행합니다.
  // 공항 이름 자동완성 기능을 수행합니다!
  findAll: (req, res) => { // 두 개의 인자(req, res)를 받는다.
    if (req.query.query !== undefined) { //함수 안에서 req.query.query 값이 정의되어 있는지 확인한다. 만약 정의되어 있으면,
      console.log(req.query.query); //  req.query.query 값을 콘솔로그 찍어준다.
      const filteredAirports = airports.filter((airport) => { // 변수 filteredAirports만들고 필터 거친다.
        return airport.code.includes(req.query.query.toUpperCase()); //airports 배열에서 code 값에 req.query.query(대문자로 변환하여)이 포함되는 것들을 걸러낸다. 
      });
      return res.status(200).json(filteredAirports); //그리고 걸러낸 결과(filteredAirports)를 JSON 형식으로 res에 200 상태 코드와 함께 반환한다.
    }
    res.json(airports);
  }
};

/*
-위 코드에서 req.query.query 란?-
req.query.query 값이 정의되어 있지 않다면, airports 배열을 JSON 형식으로 res에 반환한다.
req.query.query는 HTTP 요청(request)의 query string에서 "query" 파라미터의 값을 나타낸다.
Query string은 URL에서 "?" 뒤에 위치하는 부분으로, 파라미터와 값의 쌍으로 구성되어 있다.
예를 들어, URL이 "http://example.com/search?query=keyword"일 경우, req.query.query의 값은 "keyword"이다.
*/

이 코드는 [GET] /airport?query={query} 요청을 수행하고 공항 이름 자동완성 기능을 하는 기능을 합니다.
airportList 모듈에서 공항 목록을 불러와 req.query.query 로 받은 값이 포함된 목록을 filteredAirports 변수에 저장하고, 200 status code 와 json 형태로 filteredAirports 를 response 합니다.

bookController.js

// POST /book에서 사용할 uuid입니다.
const { v4: uuid } = require('uuid');
// 항공편 예약 데이터를 저장합니다.
let booking = [];

module.exports = {
  // [GET] /book 요청을 수행합니다.
  // 전체 예약 데이터를 조회합니다.
  findAll: (req, res) => {
    return res.status(200).json(booking);
  },
  //모든 예약 데이터를 가져오는 기능. 데이터는 booking 변수에 저장되어 있고, HTTP 응답 상태가 200(OK)이고 JSON 형식의 데이터로 리턴.

  // [GET] /book/:phone 요청을 수행합니다.
  // 요청 된 phone과 동일한 phone 예약 데이터를 조회합니다.
  findByPhone: (req, res) => {
    const {phone} = req.params;
    // TODO: 
    // phone 쿼리가 참일때
    // req.params로 전달받은 phone 값에 따라 booking 데이터를 필터링하여 list 변수에 담고, json 형태로 res.json() 메소드를 통해 응답
    let list = booking;
    if(phone){
      list = list.filter((item) => {
        return item.phone === phone
      });
      return res.json(list);
    }
  },
  // [GET] /book/:phone/:flight_uuid 요청을 수행합니다.
  // 요청 된 id, phone과 동일한 uuid, phone 예약 데이터를 조회합니다.
  findByPhoneAndFlightId: (req,res) => {
    const {phone, flight_uuid} = req.params;
    // TODO:
    let list = booking;
    if(flight_uuid){
      list = list.filter((item) => {
        return item.flight_uuid === flight_uuid;
      })
      res.json(list);
    }
    else if(phone){
      list = list.filter((item) => {
        return item.phone === phone;
      })
      res.json(list);
    }
    return res.json(list);
  },
  // [POST] /book 요청을 수행합니다.
  // 요청 된 예약 데이터를 저장합니다.
  create: (req, res) => {
    // POST /book에서 사용할 booking_uuid입니다.
    const booking_uuid = uuid();
    // TODO:
    // POST 메소드로 /book 에 요청을 보낼 때, booking_uuid라는 고유한 식별자를 만들고, 그 값이 있다면 req.body의 값을 booking 배열에 push하고, json 형태의 {} 를 response하는 기능
    if(booking_uuid){
      booking.push(req.body)
    }
    return res.json({}) 
  },

  // Optional
  // [DELETE] /book/:booking_uuid 요청을 수행합니다.
  // 요청 된 id, phone 값과 동일한 예약 데이터를 삭제합니다.
  deleteByBookingId: (req, res) => {
    const {booking_uuid} = req.params;
    // TODO:
  }
};

flightController.js

const flights = require('../repository/flightList');
const fs = require('fs');

module.exports = {
  // [GET] /flight
  // 요청 된 파라미터 departure_times, arrival_times 값과 동일한 값을 가진 항공편 데이터를 조회합니다.
  // 요청 된 파라미터 departure, destination 값과 동일한 값을 가진 항공편 데이터를 조회합니다.
  
  // 배열의 형태여야 합니다 > filter 통과값은 배열로 반환
  findAll: (req, res) => {
    const { departure_times, arrival_times, destination, departure } = req.query;
    // TODO:
    if(departure_times && arrival_times){
      const filterDepartureTimes = flights.filter((list)=>{
        return list.departure_times === departure_times && list.arrival_times === arrival_times;
      })
      return res.json(filterDepartureTimes);
    }
    if(departure && destination){
      const filterDeparture = flights.filter((list)=>{
        return list.departure === departure && list.destination === destination;
      })
      return res.json(filterDeparture);
    }
    return res.json(flights); //파싱 가능한 JSON 문자열을 돌려줘야 합니다
  },

  // [GET] /flight/:uuid
  // 요청 된 uuid 값과 동일한 uuid 값을 가진 항공편 데이터를 조회합니다.
  findById: (req, res) => {
    const { uuid } = req.params;
    // TODO:
    if(uuid){
      const filterUuid = flights.filter((item)=> {
        return item.uuid === uuid;
      })
      return res.json(filterUuid);
    }

  },

  // Advanced
  // [PUT] /flight/:uuid 요청을 수행합니다.
  // 요청 된 uuid 값과 동일한 uuid 값을 가진 항공편 데이터를 요쳥 된 Body 데이터로 수정합니다.
  update: (req, res) => {
    const { uuid } = req.params;
    const bodyData = req.body; // 바디데이터 초기값 undefined -> json parser 해야..
     // TODO:
     // uuid 값과 동일한 
    if(uuid){
      // 동일한 uuid 값을 가진 항공편 데이터
      // uuid 필터 배열반환 된것 바디데이터에 추가
      // {
      //   uuid: 'af6fa55c-da65-47dd-af23-578fdba40bed',
      //   departure: 'ICN',
      //   destination: 'CJU',
      //   departure_times: '2021-12-02T12:00:00',
      //   arrival_times: '2021-12-03T12:00:00'
      // },
      // [{uuid:'af...'}] 형태로 가져오게됨.
      const filterUuid = flights.filter((item)=> {
        return item.uuid === uuid;
      });
      // 바디에 추가 - 객체를 응답으로 보냅니다
      // Object.assign() 
      // 메서드는 출처 객체들의 모든 열거 가능한 자체 속성을 복사해 대상 객체에 붙여넣습니다. 
      // 그 후 대상 객체를 반환합니다. 리턴하는 값이 그러하다..
  
      //{uuid:'af...'} 바디에 추가
      let result = Object.assign(filterUuid[0], bodyData)
      return res.json(result);
          
      // const updatedFlight = {...filterUuid[0], ...bodyData};
      // return res.json(updatedFlight);
      // Object.assign 메소드와 spread operator (...) 는 객체 병합을 수행하는 기능을 갖습니다.
    } 
  } 
};

 

포스트맨으로 제대로 가져오는지 확인!

'프론트엔드 공부 > Web Server' 카테고리의 다른 글

세션(블로깅중)  (0) 2023.03.07
쿠키란 무엇일까? 개념, 필요성, 속성, 문제점  (0) 2023.03.07
[Web Server] 기초 종합퀴즈  (0) 2023.02.08
Mini Node Server  (0) 2023.02.06
SOP, CORS  (0) 2023.02.06
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.