그저 내가 되었고

항해99) 3주차:: 주특기 입문; 📚Express.js 본문

개발/항해99 9기

항해99) 3주차:: 주특기 입문; 📚Express.js

hyuunii 2022. 10. 3. 11:46

1. 준비하기

Express.js란?

- 네가 지금 Node.js를 배우는건 웹서버를 만들기 위해서야.

- 그와중에 익스~는 노드로 서버를 빠르고 간편하게 만들 수 있게 도와주는 웹 프레임웤임.

- 뭐.. 익스~ 외에도 많은데 얘가 노드로 만든 웹서버 중에 가장 주류임.

정리) 익스~는 웹 서버 자체가 아님. 노드를 위한 웹서버 구축용 프레임웤.

 

Express.js로 웹서버를 만들고싶으면?

1) 폴더 하나 만들고(hyuunii_mall 등)

 

2) 웹스톰 들어가서 그 폴더 안에 app.js 만들고

 

3) 터미널에 npm init -y 쓰고 packaga.json 생성(뒤의 y? 이거 설치할때 프로젝트명이나 버전같은거 물어보는데 나는 귀찮고 답 안할테니 니 알아서 해라 하는 명령ㅋ)

 

4) 설치 완료되면 폴더 밑에 package.json 들어와 있을 것(열어보면 자동생성된 json파일이 적혀 있을 것

 +터미널에서 npm i express 치고 Express.js 프레임웤 설치하는 과정도 있는데, 이건 아마 딱 한번만 하는게 아닐꽈?

 + package-lock.json은 어떤 패키지들이 어떤 버전으로 설치되었는지 기록해놓은 파일. 이 파일이 있으면 협업할때 같은 환경으로 개발할 수 있게 도와줌

 + node_modules 폴더는 npm을 통해 설치된 패키지들에 대한 파일이 있는 폴더. 앞으로 개발을 하면서 다양한 라이브러리를 사용할텐데 이에 대한 모든 파일이 여기에 설치됨

 

5) app.js 예시!👇🏻

const express = require('express');  //express 라이브러리를 express라는 변수에 담고
const app = express();  //app이라는 변수를 만들어 express를 새롭게 할당. 그러면 일반적 서버 사용 위한 app 객체 생성됨.
const port = 3000;

app.get('/', (req, res) => {  //기본 url(/)에 req와 res를 받아서 실행하는 api를 만드는 것
  res.send('반가워용✨!');  //기본 url에 접근하면 반가워용 메세지 받는 api를 만들고
});

app.listen(port, () => {  //포트로 서버 열어준다는 뜻. 이거 그냥 위에서 const port 안하고 바로 이 줄의 port 자리에 3000 적어도 됨
  console.log(port, '포트로 서버가 열렸어요!');  //서버 잘 열리면 콘솔에 port num+ 문구 찍어줌
});

6) 바로 app.js 실행시키면 실행창에 “3000 포트로 서버가 열렸어요!” 잘 뜰 것~! 그러면 서버 실행된 것~~~!

 + 만약 실행에 문제가 있다?!👇🏻

Error: listen EADDRINUSE: address already in use :::3000
    at Server.setupListenHandle [as _listen2] (net.js:1318:16)
    at listenInCluster (net.js:1366:12)
    at Server.listen (net.js:1452:7)
// 혹시 위와같은 에러가 나오나요? 이미 다른 프로그램이 해당 포트를 사용중일 수 있음.
// app.js 파일에서 3000 이라고 써져있는 port를 다른 숫자로 변경하면 그만~!

+ 이미 실행중인 포트를 찾아서 종료하려면?!👇🏻

1) cmd창에서 이 명령어(netstat -ano | find "원하는포트")를 입력, 내가 원하는 포트 정보를 찾자

2) 해당 포트를 점유하고있는 PID 찾아서 kill(taskkill /f /pid 12952)

 

7) 이거 잘 돌아가는지 확인하려면?!

- 브라우저에서 http://localhost:3000/ (포트 번호 바꿨으면 바꾼데루) 경로로 ㄱㄱ

- GET Method로 작성된 코드를 통해 반가워용✨! 라는 문구를 확인

 

 

API Client?

1) 머여 이건? 이건 개발 할 때 우리가 쓴 API의 요청을 확인하거나 테스팅할 때 도움을 주는 툴. 개발 속도 up, 치명적 에러 예방에 도움 받을 수 있음(난 postman에 정착~!)

 

2) 언제 필요할까? 음. 지금까지는 HTTP MEthod 중 GET에 해당하는 API만 만들고 브라우저만 확인했지(반가워용!) 뭐 이러면.. 그닥 필요 없어 보이겠지만, POST, PATCH, PUT, DELETE, HEAD 등 다양한 Method에 대한 API를 개발하고 테스트하려면 반드시 얘를 써야 함!!


2. 시작하기

Routing 이해 및 Router 학습

//추신; 루트 맞는데..ㅋㅋㅋㅋ CS에서는 좀 달리 읽기도 하나봄ㅎㅋ...

 

1) Routing이란? 클라이언트의 요청 조건(http 메서드, 주소 등)에 대응해 응답하는 방식?.......?🤔

- ㅎ... 음, 웹 프레임웤을 배울 때, 내가 처음으로 찾아봐야 할 건 '이 프레임웤은 라우팅은 어떻게 하는거지?!' 이거얌. 이걸 알면 반은 한거야~~! 왜!!??! 웹 프레임웤이 하는 본질적인 일이 바로 라우팅이거덩.

- 뭔솔? 

 +일단, 서버를 구축하면 Express.js와 내 앱이 셋팅 되어 잇겠지?

 +그 서버에 접속하는 주소는 기본 url부터 시작해서 그 뒤에 /read/1(id가 1인 글을 읽는 주소), /goods/cart 등등 다양할 수 있어

 +그러면! 각각의 주소를 입력해서 들어오는 요청을 담당할 담당자가 필요하자나~!

 +이때, 어떤 요청을 누가 담당할거고 응답할건지 연결시켜주는 작업이 필요해. 그런 작업을 라우팅이라고 하는 것(wow)

 +그런 작업을 기술하는걸 router라고 함. 클라이언트의 요청을 쉽게 처리할 수 있도록 도와줘.

- 이전에 router를 이미 만들어 보기도 했어! express를 처음 띄웠을 때 예시로 app.get을 통해 라우터를 만들어서 기본 url로 접근하면 반갑다는 문구 띄워줬자나!! 이것도 라우터를 통해 라우팅을 했다고 볼 수 있는 것이쥐

- 이렇게 지금까지는 app.get과 같이 app.~으로 http method를 통해 만들었다고 한다면, 이번에는 라우터를 통해서 만들어볼게.

 

2) Router

일반적으로 아래👇🏻와 같은 구조를 가져.

router.METHOD(PATH, HANDLER);

- router: express의 router을 정의

- METHOD: HTTP Method를 나타내(get, post, put 이런거..)

- PATH: 실제 서버에서 API를 사용하기 위한 경로!!!

- HANDLER: 라우트가 일치할 때 실행되는 함수~!

 

3) 라우터 저눔은 어떻게 쓰는디.. 

- 일단 routes 폴더를 생성~! 글고 그 안에 goods.js라는 파일 만들어봅시당

- express에서 제공되는 라우터 함수(express.Router())로 라우터를 생성하자!(오,, 사스가 웹프레임웤,,,)👇🏻

// routes/goods.js
const express = require('express');  //express 라이브러리를 express라는 변수에 담고
const router = express.Router();  //express라는 객체(라이브러리?) 안의 라우터 함수를 실행해서 그 결괏값을 라우터라는 변수에 할당
//실제로 api를 만들거나 라우터를 생성할 때는 이렇게 router라는 변수를 통해 사용한당!

- 글고 저 라우터를 이용해서 예시로 endpoint도 작성해볼게👇🏻

 +엔드포인트? API가 서버에서 리소스에 접근할 수 있도록 가능하게 하는 URL

// routes/goods.js
router.get('/', (req, res) => {  //위에서 반환 받은 라우터라는 변수로, 라우터를 만들자~!
//기본url로 받는 API(기본 경로로 들어온 get 메소드)에서 req랑 res객체 받아서 실행할게~!
//실제로 API를 실행할 때, API에 받은 데이터는 req라는 객체에 들어있다~!
	res.send('this is home page');  //위에서, 기본 경로로 들어온 get 메소드는 res.send로 send 안의 값을 반환
});

router.get('/about', (req, res) => {  //router라는 변수를 써서 about이라는 기본 말고 추가적인 경로로 실행하는 API(get 메소드 호출)
//& 실제로 실행할 req, res객체를 가지는 하나의 함수를 만든 것~!
	res.send('this is about page');  //about이라는 라우터에 왔을 때 반환할 값~!
});

- 글고 작성한 라우터 변수를 app.js에서 사용하기 위해서, 코드 하단부에 너는 모듈이다 나가라!!!는 코드 추가~!

// routes/goods.js
module.exports = router;  //good.js 파일 내의 routes를 반환한다~!

- 그 빼준 모듈을 app.js에서 전역 미들웨어로 사용하겠다고 작성하면,

 +middleware? 웹 서버 즉 express에서 요청을 받을 때, 가끔 모오든 요청에 대해 공통적인 처리를 하고 싶을 수 있지. 그럴때 미들웨어를 이용해. 웹 서버의 요청/응답에 대해 공통적으로 관리가 가능하거든. 이후에 app.use와 같이 전역으로 사용할 때는 저렇게 use라는 문법을 통해서 미들웨어를 등록한다고 보면 될 것 같당.

// app.js
const goodsRouter = require("./routes/goods");  //굿즈라우터라는 변수에다가 라우츠라는 폴더 안에 있는 goods.js라는 파일을 가져올거다!
// ./는 상대 경로를 나타내요. 그게 먼데? 걍 현재 지금 폴더라고 생각하셈(app.js 위치한 최상위폴더). 
//글고 이 최상위 폴더 내에 app.js가 있잖아. 그럼 일단 routes라는 폴더를 찾을거고(./routes) 고담에 거기서 goods라는 파일 찾을거라서(/goods) 저렇게 쓴겨
//anyway.. 아까 goods.js에서 반환한 라우터가 여기에서 goodsRouter라는 변수에 할당되었다!!!!
app.use("/api", [goodsRouter]);  //반환받은 라우터를 실제로 익스프레스에다가 적용시켜보자.
// app.use라는 문법 통해서 적용시킬건데(API를 등록시킬건데), app.use는 app이라는 익스프레스 객체에다가(const app = express();) 전역으로 쓸거란 뜻!
// 모든 미들웨어가 여기를 통과하게끔 할거다!! 란 뜻.. 
// 나는 Express.js가 위에서부터 아래로 실행된다는걸 기억하자! 그러다가 app.use가 있다면 여기부터 통과하고!!(비동기) 담으로 넘어가란 뜻!
// goods.js에서 여러 API를 만들었잖아(get같은거..). 그러면 걔들은 그 모듈 내에서 위에서부터 아래로 차례대로 읽혀.
// 글고 app.js에서도 코드 전체가 위에서 아래로 읽히는데, 만약 app.use가 app.get('/'~) 위에 위치한다면?
// app.use 전부를 다 거친 다음에!!! app.get이 읽힌다는 뜻. 그러니까 app.get('/'~) 뒤에 app.use를 적어줘야지만
// app.get('/'~)을 검사한 뒤에!!! 미들웨어로 넘어가서 app.use가 읽힌다~
// 여기서는 사용할 경로를 추가한 다음에("/api"), 이 경로로 들어온 나머지들은 다 [goodsRouter]로 가란것

 

- 이제부터 http://localhost:3000/ 뒤에 /api로 시작되는 주소는 routes/goods.js에 있는 라우터 미들웨어를 통해 처리됨!

- 참고 문법)

//app.js
const goodsRouter = require("./routes/goods.js");
app.use("/api", [goodsRouter]);
//이렇게 goodsRouter 선언할 때, 단순하게 goods.js 파일 하나에서만 가져오는게 아니라
//postRouter, usersRouter 등등 생길 수 있어. 얘들 하나하나 적지 않아도 되고,
//[goodsRouter, postRouter, usersRouter...]이렇게 배열로 적을 수도 있음~!

 

 

Module의 이해

1) 그게 먼데..

- 분리된 JS 파일이고, 각 파일은 특정 기능을 가진 여러 함수와 변수들의 집함임

- Module을 만들면 다른 프로그램에서 해당 모듈을 재사용할 수 있음

- Module은 그 자체로도 하나의 프로그램이면서 다른 프로그램의 부품으로도 사용할 수 있음

- 보통 한개의 파일이 한개의 모듈

 

2) 어떻게 사용하는디..

- exports 명령어를 변수나 함수 앞에 붙이면 외부 모듈에서 해당 변수나 함수에 접근할 수 있음

- import, require 명령어를 사용하면 외부 모듈의 기능을 가져올 수 있음

 + import vs require?

  - 자바스크립트는 대표적으로 CommonJS, ES6(ES2015) 방식으로 모듈 시스템을 관리 가능

  - require은 현재 학습중인 CommonJS로 모듈 시스템을 관리할 때 사용

  - improt는 ES6로 모듈 시스템 관리할 때 사용

 

3) 함 써볼까..?(only 실습용!!)

- module 폴더 만들어서 math.js와 run.js를 생성해보쟝

- 2가지의 인자를 입력받았을 때 값을 더해주는 함수를 생성👇🏻

// modules/math.js
function add(a, b) {
 return a + b;
}

- 그리고 작성한 함수를 다른 모듈로 내보내주기 위해 하단에 코드를 추가👇🏻

// modules/math.js
module.exports = add;

- run.js에서 불러들인 add함수를 사용하도록 작성👇🏻

// modules/run.js
const add = require("./math");
console.log(add(3, 4));
// Print: 7

 

 

 

Request와 Response

1) 그게 먼데.. 걍 이름 뜻이랑 거의 비슷함

Request? 클라 ⭆ 서버로 전달하려는 정보나 메세지 담은 객체

Response? 서버 ⭆ 클라로 응답 메세지를 전송시켜주는 객체

 

2) 서버 모듈

- Node.js의 서버 모듈에는 대표적으로 http 모듈과 Express 모듈이 존재

- Express 모듈은 http 모듈(노드가 제공하는 기본 모듈)을 확장하여 제공(Express 모듈은 기존 http 모듈의 메서드도 사용할 수 있지만, Express가 추가 제공하는 메서드나 속성들을 사용할 수 있다는 뜻)

- 최근에는 Express의 메서드가 더욱 편리하기에 기존 http 모듈의 메서드는 잘 사용되고 있지 않음~!

 

3) Express 모듈의 req, res 객체

req 객체(클라이언트가 받고싶은게 있대요. 거기다가 이런저런 서류 첨부해서 요청해와유)

- req.app: req 객체를 통해 app 객체에 접근할 수 있음

- req.ip: 요청한 클라의 ip 주소가 담김

- req.body: request를 호출할 때(클라曰: 있잖아/서버曰: 너 뭐 원해 클라이언트?) body로 전달된 정보가 담긴 객체(body-parser Middleware를 이용해야-app.use(express.json());- req.body 사용 가능)

- req.params: 라우터 매개 변수에 대한 정보가 담긴 객체(매개변수 설정해서 특정 url 뒤의 모든 데이터는 매개변수로 본다!, 정보가 담긴 모든 내용은 매개변수로 출력한다!)

- req.query: request를 호출할 때 쿼리 스트링(url 뒤에 물음표 쓰고 전달)으로 전달된 정보가 담긴 객체

- req.cookies: Request를 호출할 때 Cookie 정보가 담긴 객체(cookie-parser Middleware를 이용하여야 해당 객체를 사용할 수 있음)

- req.get(Header): 헤더에 저장된 값을 가져오고 싶을 때 사용

+ req.body
 방금까지 실습한 내용에서는, app.js에서 app.use("/api", [goodsRouter]);까지 되어있는데 api에 경로를 추가해서 goodsRouter로 가기 위한 방법을 app.use로 구현함.

1] body parser middleware 등록(for 전역 미들웨어를 사용)
 이번엔 전역 미들웨어, 즉 모든 코드(API)에서 동작하는 미들웨어를 사용하기 위해서 맨 윗단의 const 애들 모여있는곳 바로 밑에 한 줄 띄우고 app.use(express.json());을 써서(바디 파서 미들웨어 등록), request라는 객체 안의 body(req.body)를 사용할 수 있게 해 줌.
 즉, 모든 코드에서 바디 파서 미들웨어를 등록해서 request 내의 body 데이터를 쓰겠다~!

2] 실제 body 데이터 사용
 body 데이터를 실제로 사용하려면? post method 쓸 때 제일 많이 씀. 
app.js에서
//req.body는 post 메소드 때 제일 많이 씀니다.
app.post('/', (req, res) => {  //기본 url에 호출하는 함수에여
    console.log(req.body);  //실제 body에 들어온 데이터를 확인할거구여
    res.send('기본 URI에 POST 메소드가 정상 실행되었어요~!')
})​
일케 적어준 후에,,

postman 가서 post에서 localhost:3000/ 적어주고
Body탭에서!!!(쿼리는 파라미터 탭이었쥬~?) json 형식으로 데이터를 적어줘여.
{
  "keykey" : "혀니쨩쨩"
}​

 

이러케,, 그러면 포스트맨 바디 창에서도, 웹스톰 실행 창에서도 네가 적은거 잘 드루옵니다용
+ req.query
router 쓰지 않고 바로 TEST하기1! app.js에서
위의 const 모여있는 단 밑에..
//router 쓰지 않고 바로 TEST
app.get('/', (req, res) => {  //기본 url에 들어왔을 때 동작하는 API 만들기~!
    console.log(req.query);  //req에 들어온, 즉 query string으로 전달 받은 데이터를 query를 변수에 할당 안하고 바로 출력한다..
    res.send("반환완료쓰~!");  //res.send로 결과값 반환
});​

 

일케 적어준 후,
postman 들어와서, localhost:3000/와 get인 상태에서
Params 탭 눌러보면 얘 역시 parameter과 value로 관리됨이 보임. param에는 key값(아무거나.. queryKey), value에는 실제 결괏값(암거나! valuevalue)넣어서 확인ㄱㄱ. 
이렇게 작성하면, localhost:3000/?queryKey=valuevalue로 바뀌는데! 쿼리 스트링 같은 경우, 일반적으로 사용하는 url 뒤에 ? 붙여서 데이터를 전달할건데, key와 value 가진 값을 쿼리 스트링으로 전달한다는 것~! 이때 key와 value는 =로 구분한다~! 
이후 send 누르면 반환완료쓰~! 뜸ㅋ
+ req.params
//req.params
app.get("/:id", (req, res) => {  //id라는 params 받도록 만듦. req, res 객체 써서 함수 만든다!!
    console.log(req.params);  //req.params를 출력할거고
    res.send(":id URI에 정상 반환되었어요~!")
})​

 

postman 들어와서, localhost:3000/하고 /뒤에 암꺼나..(iluvuu) 치면ㅋㅋㅋㅋㅋ
postman body창에는 :id URI에 정상 반환되었어요~!, 웹스톰 실행창에는 { id: 'iluvuu' }가 잘 들어온당

왜?! 나는 그냥 console.log(req.params)로 출력만 했는데?! 왜 id라는 키를 가지고 iluvuu라는 밸류를 가진 객체가 반환된 것 확인 가능. 왜 id라는 키로 반환? uri 뒤에다가 id라는 키로 받겠다고 :id(콜론 id)를 표시해준거잖어~

결론!!! 라우터의 매개변수가 id라는걸 통해서 params에 할당된다!!!

 

res 객체(클라의 요청에 실제로 응답으로 들어가유)

- res.app : res 객체를 통해 app 객체에 접근할 수 있음

- res.send(데이터) : 데이터를 포함하여 Response를 전달

- res.json(JSON) : JSON 형식(JS의 객체식으로 표현하는 파일 형식)으로 Response를 전달 👇🏻

//res.json? 실제로 응답으로 들어가는 것.
app.get('/', (req, res) => {
    console.log(req.query);

    const obj = {
        "key": "value",
        "이름": "이름?",
    }

    res.json(obj);  //json이란 문법 통해 반환. 얘는 단순하게 객체 형태로 바로 넣어도 됨(위의 const obj)
    // 글고!!! 변수로 const obj 만드는게 아니라.. 그냥 json( )여기 괄호 안에 저 obj 뒤의 { }부분 전부 갖다 넣어도 됨~!!
});

- res.status(코드) : Response에 HTTP 상태 코드를 지정 👇🏻

//글고 json 형태로 반환하면 기본적으로 status200인데, 오류가 난 것 처럼 표시하고싶다?
res.status(400).json({
  "key": "value",
  "이름": "이름?",
  }); //이렇게 써주면 됨~! 이후 postman에서 get에 기본 url에 sen 찍어보면 status가 400 Bad Req로 뜸

- res.end() : 데이터 없이 Response를 전달

- res.direct(주소) : 리다이렉트할 주소와 함께 Response를 전달

- res.cookie(Key, Value, Option) : 쿠키를 설정할 때 사용

- res.clearCookie(Key, Value, Option) : 쿠키를 제거할 때 사용

 

 

API & REST API

1) API(Application Programming Interface): 애플리케이션끼리 연결해주는 매개체이자 약속(연결고리~~~~!)

 

2) 우엥.. 뭐여 저게...

- 키보드로 글자를 입력하면 키보드는 우리가 작성한 글자를 컴퓨터에 전달해주는 역할을 함. 키보드의 키를 누르는것이 API를 호출

- 어떤 연인은 서로 기분이 상할것 같으면 미리 “윙크”를 하기로 약속. 대화하다 갑자기 “윙크”를 본 상대방은 기분이 나쁜것을 알아채고 은근히 기분을 풀어주려 노력함, 윙크가 API 호출

 

3) API 작성?

- 웹 어플리케이션(프론트엔드)에서 원하는 기능을 수행하는 URL인터페이스제공

- 네가 작성할 API에서 원하는 데이터 받고, db에 걔를 저장하고, 저장된 데이터를 잘 읽어서 프론트에 잘 보내줘야 함

- 그래서 사용자가 원하는 목적을 틀림 없게 이루게 해야 함

 

4) 그래서.. REST API는?

- 여기서 REST는 “Representational State Transfer”임.

- ?구상주의적이 왜나와?  URL, Headers, Method 등 네트워크 표현 수단을 사람이 보더라도 이해하기 쉬운 표현으로 정의하는 룰

- REST Architecture? 사람이 봐도 쉽게 이해할 수 있도록 “자원”을 정의하고 이 “자원”을 중심으로 표현을 구성하는 원칙을 제시(아 그래서 representational이구나..)함. 그래서! REST API는 “REST Architecture”라는 규칙을 따르는 API(연결고뤼)

- REST API의 구성?

1) 자원(Resource) - URL; 우리가 만들 소프트웨어가 관리하는 모든 것은 자원. 쇼핑몰이라면 상품(Goods)에 대해서 정보를 관리할거고, 장바구니(Carts)에 담긴 상품들도 관리 할 것.

2) 행위 - HTTL method; get, post, put 이런 애들로 해당 자원에 대한 행위를 표현할 수 있음. 일반적으로 CRUD를 행함. 

  Create : 생성(POST)
  Read : 조회(GET)
  Update : 수정(PUT),(PATCH)
  Delete : 삭제(DELETE)

3) 표현: 해당 자원을 어떻게 표현할지에 대한 설명. 보통 JSON, XML같은 형식을 이용해서 표현함. HTTP에서는 Content-Type이라는 헤더를 통해 표현 방법을 서술함.

4) 예시

router.get('/books', (req, res) => {
	res.json({ success: true, data: getAllBooks() });
});

- 위의 이 코드는, /books라는 URL을 통해 책 전체 목록을 불러와 응답해주는 API임

- 위의 API를 REST API의 관점에서 보면? URL로 리소스를 구분하고  다른 표현이 없으므로 전체 리스트를 불러오는 것이라 짐작 가능.

- CRUD 중 Read를 담당하는 HTTP 메소드를 표현하여 REST한 API라고 볼 수 있음


3. REST API 개발

잠깐!!!! REST API!? “REST Architecture”라는 규칙을 따르는 API(연결고뤼)

 

1) 상품 목록 조회 API 구현하기

어뜨케 해야할까요,,,

- 상품 목록 조회 API에서는 모든 상품이 한번에 다 나올 수 있어야 해요!

- 예컨대 get 메소드를 이용해서 /goods라는 주소로 들어갔을 때, 모든 상품 목록이 response로 응답해서 json포맷으로 상품 목록이 보여야 해요

- 이번 주차에서는 db를 사용하지 않으니꽈.. routes 폴더에 goods.js 파일에 아래의 json 예시 데이터를 저장해주도록 할게요!

더보기
// /routes/good.js
const goods = [
  {
    goodsId: 4,
    name: "상품 4",
    thumbnailUrl:
      "https://cdn.pixabay.com/photo/2016/09/07/02/11/frogs-1650657_1280.jpg",
    category: "drink",
    price: 0.1,
  },
  {
    goodsId: 3,
    name: "상품 3",
    thumbnailUrl:
      "https://cdn.pixabay.com/photo/2016/09/07/02/12/frogs-1650658_1280.jpg",
    category: "drink",
    price: 2.2,
  },
  {
    goodsId: 2,
    name: "상품 2",
    thumbnailUrl:
      "https://cdn.pixabay.com/photo/2014/08/26/19/19/wine-428316_1280.jpg",
    category: "drink",
    price: 0.11,
  },
  {
    goodsId: 1,
    name: "상품 1",
    thumbnailUrl:
      "https://cdn.pixabay.com/photo/2016/09/07/19/54/wines-1652455_1280.jpg",
    category: "drink",
    price: 6.2,
  },
];

- 이후 localhost:3000/api/goods에 접속했을 때 아래처럼 나오면 잘 작동된거에여~!

더보기
{
  "goods": [
    {
      "goodsId": 4,
      "name": "상품 4",
      "thumbnailUrl": "https://cdn.pixabay.com/photo/2016/09/07/02/11/frogs-1650657_1280.jpg",
      "category": "drink",
      "price": 0.1
    },
    {
      "goodsId": 3,
      "name": "상품 3",
      "thumbnailUrl": "https://cdn.pixabay.com/photo/2016/09/07/02/12/frogs-1650658_1280.jpg",
      "category": "drink",
      "price": 2.2
    },
    {
      "goodsId": 2,
      "name": "상품 2",
      "thumbnailUrl": "https://cdn.pixabay.com/photo/2014/08/26/19/19/wine-428316_1280.jpg",
      "category": "drink",
      "price": 0.11
    },
    {
      "goodsId": 1,
      "name": "상품 1",
      "thumbnailUrl": "https://cdn.pixabay.com/photo/2016/09/07/19/54/wines-1652455_1280.jpg",
      "category": "drink",
      "price": 6.2
    }
  ]
}

- goods.js 예시

더보기
// /routes/goods.js
const express = require("express");

const router = express.Router();

const goods = [
  {
    goodsId: 4,
    name: "상품 4",
    thumbnailUrl:
      "https://cdn.pixabay.com/photo/2016/09/07/02/11/frogs-1650657_1280.jpg",
    category: "drink",
    price: 0.1,
  },
  {
    goodsId: 3,
    name: "상품 3",
    thumbnailUrl:
      "https://cdn.pixabay.com/photo/2016/09/07/02/12/frogs-1650658_1280.jpg",
    category: "drink",
    price: 2.2,
  },
  {
    goodsId: 2,
    name: "상품 2",
    thumbnailUrl:
      "https://cdn.pixabay.com/photo/2014/08/26/19/19/wine-428316_1280.jpg",
    category: "drink",
    price: 0.11,
  },
  {
    goodsId: 1,
    name: "상품 1",
    thumbnailUrl:
      "https://cdn.pixabay.com/photo/2016/09/07/19/54/wines-1652455_1280.jpg",
    category: "drink",
    price: 6.2,
  },
];

//상품 목록 조회 API
router.get("/goods", (req, res) => {
	res.json({ goods: goods });
});

 

 

2) 상품 상세 조회 API 구현하기

어뜨케 해야혀,,, 

- 여기선 특정 상품의 상세 조회를 위해서 기존 상품 목록 주소 이후에 URL Params로 상품 id를 보내줘서 걔를 조회하도록 해야됨!

- URL Params?! 라우터 주소에 쓰이는 특수한 패턴 중 하나쥬. 예컨대 상품 목록 조회 API의 주소가 /goods라면 그 뒤에 /:goodsId라는 값을 추가해서 요청시 id값을 받아올 수 있어! 이 값은 API 내에서 req.params 객체 안에 든 것을 확인 가능쓰

- 긍까.. 만약에 http://localhost:3000/api/goods/1 일루 들어갔따고 쳐바잉 그라믄 아래처럼 나와여.

더보기
{
  "detail": {
    "goodsId": 1,
    "name": "상품 4",
    "thumbnailUrl": "https://cdn.pixabay.com/photo/2016/09/07/02/11/frogs-1650657_1280.jpg",
    "category": "drink",
    "price": 0.1
  }
}

- goods.js 예시

더보기
router.get("/goods/:goodsId", (req, res) => {
    const express = require("express");
    const router = express.Router();
    const goods = [
        {
            goodsId: 4,
            name: "상품 4",
            thumbnailUrl:
                "https://cdn.pixabay.com/photo/2016/09/07/02/11/frogs-1650657_1280.jpg",
            category: "drink",
            price: 0.1,
        },
        {
            goodsId: 3,
            name: "상품 3",
            thumbnailUrl:
                "https://cdn.pixabay.com/photo/2016/09/07/02/12/frogs-1650658_1280.jpg",
            category: "drink",
            price: 2.2,
        },
        {
            goodsId: 2,
            name: "상품 2",
            thumbnailUrl:
                "https://cdn.pixabay.com/photo/2014/08/26/19/19/wine-428316_1280.jpg",
            category: "drink",
            price: 0.11,
        },
        {
            goodsId: 1,
            name: "상품 1",
            thumbnailUrl:
                "https://cdn.pixabay.com/photo/2016/09/07/19/54/wines-1652455_1280.jpg",
            category: "drink",
            price: 6.2,
        },
    ];

//const goodsId = req.params.goodsId; 파라미터 내의 goodsId를 꺼내는 것. 원래 이렇게 했는데 얘를 좀 더 다르게 하려면!!
    const {goodsId} = req.params;  //params 안의 goodsId는 오브젝트라서 객체 구조 분해 할당을 해서 간단하게 처리하면 됨!
    //위의 주석 처리한 const goodsId랑 얘랑은 똑같지만, 이번엔 객체 구조 분해 할당을 사용하는 것~!
    //이렇게 URL 파라미터에 들어온 데이터를 {goodsId}라는 변수에 할당했드아
    const [detail] = goods.filter((item) => {item.goodsId === Number(goodsId)});  //입력받은 굿즈 id와 일치하는 것들을 필터링하는 API를 만들겠으~!
    //근데 지금 goods가 array 형식으로 되어 있으니까,, 진짜로 filter 메쏘드 쓴 것~~!ㅋ
    //goods 안의 데이터들을 item으로 정의하고, 입력받은 req.params의 goodsId와(string으로 들어오니까 num처리 한 후)
    //그 item의 goodsId가 정확히 같은지 췤췤해서 detail이란 변수에 할당한다!!
    res.json({"detail": detail});  //이 detail 변수 내의 정보를 json으로(detail이라는 key값 이용해서) 변환합니다유.
    //즉! 우리가 확인한 하나의 데이터(특정 id 한개)만 detail이란 key값의 value로 반환한다~!
})