[프로그래머스] 백엔드기초(8)

Lina Hongbi Ko·2024년 9월 6일
0

Programmers_BootCamp

목록 보기
17/76
post-thumbnail

2024년 9월 6일

✏️ 핸들러 & if문

  • 핸들러 : 요청에 의해 호출 되는 메서드
    ex) HTTP request가 날아오면 자동으로 호출되는 메서드
    노드 : 콜백함수로, app.HTTPmethod(path, 핸들러)
    cf) 스프링 : 컨트롤러

*if문을 쓸 때, 긍정문을 먼저 쓰는게 클린코드!

if(youtuber) {
	const channelTitle = youtuber.channelTitle
	db.delete(id)
	res.json({
		message : `${name}님, 다음에 또 봐요!`
	})
} else {
	res.json({
      message: `${id}번은 가입된 유튜버가 아니에요`,
  });
}

✏️ json array & 예외처리

// exception-demo.js

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

app.listen(1234);

const weathers = [
	{ id : 1, name : 'sunny'},
	{ id : 2, name : 'cloudy'},
	{ id : 3, name : 'rainny'}.
	{ id : 4, name : 'windy'}
]
// 프론트엔드에게 json을 여러개 보낼 때 사용하는 방법 -> json 배열

// 날씨 전체 조회
app.get('/weathers', function(req, res) {
	res.json({weathers}); // json array
})

// 날씨 개별 조회
app.get('/weathers/:id', function(req, res) {
	let id = req.params.id;
	// let weather = weathers[id-1];
	// 인덱스는 0부터 시작해야하므로 -1를 해서 순서를 맞춰준다 (첫번째 방법)
	
	// 배열의 객체 중, 해당 id가 맞는 아이 찾기 (두번째 방법)
	// 자바스크립트 배열에서 사용할 수 있는 메서드
	// 배열에서 조건에 맞는 어떤 값을 찾을 때 사용
	// weathers 배열 안에 있는 객체 중, id 값이 params.id랑 같은
	// 객체를 찾겠다는 뜻
		let findWeather = weathers.find( (weather) => weather.id == id);
	  // find 함수 의미
	  // weathers.forEach((weather)=>{
		//	if (weather.id == id) {
		//		findWeather = weather
		//	}
	})
	res.json(weather);
})
  • 전체 조회

  • 개별 조회

  • 이제 예외 처리를 해보자(없는 id로 접속)
    - 먼저, POSTMAN : localhost:1234/weathers/9 접속

왜 200 OK라고 성공된 것 같은 결과가 처리 될까?

  • 예외를 넣어서 다시 보자
  • 예외를 터뜨리는 이유 : 프론트엔드가 데이터를 받을 때 성공했다는 뜻으로 받을까봐 겁이남 -> 성공해서 데이터를 받은게 아니라 성공을 못해서 데이터가 없는 것임
  • HTTP 상태 코드는 클라이언트(사용자, 화면)와 소통을 정확하게 하기 위해서 쓰는 것임
// exception-demo.js

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

app.listen(1234);

const weathers = [
	{ id : 1, name : 'sunny'},
	{ id : 2, name : 'cloudy'},
	{ id : 3, name : 'rainny'}.
	{ id : 4, name : 'windy'}
]

// 날씨 전체 조회
app.get('/weathers', function(req, res) {
	res.json({weathers})
})

// 날씨 개별 조회
app.get('/weathers/:id', function(req, res) {
	let id = req.params.id;
	let findWeather = weathers.find( (weather) => weather.id == id);
	if(findWeather) {
		res.json(findWeather)
	} else { // 예외를 넣음
					 // http satus code를 넣어 구분
		res.satus(404).send("입력한 id로 저장된 날씨가 없어요")
		// 임의로 코드 줄 수 있음
		// 찾는 리소스가 없다는 의미인 404를 줌
		// 그리고 메시지도 같이 보내줌
	}
})

✏️ == vs ===

// equal-demo.js

// ==, ===의 차이

// == -> 자료형 상관없이 값만 비교
if(1 == "1") {
	console.log("같음");
} else {
	console.log("같지 않음");
}
// 결과값 : 값음

// === -> 자료형과 값 둘 다 비교
if(1 === "1") {
	console.log("같음");
} else {
	console.log("같지 않음");
}
// 결과값 : 같지 않음
let id = req.params.id;
let weather = weathers[id-1];
let findWeather = weathers.find( (weather) => weather.id == id);
// 위의 코드를 보면 id는 문자열인데, 마이너스 연산을 했고,
// param은 문자, id는 숫자인데 같다고 생각했다

// 이처럼 자바스크립트는 자료형을 꼼꼼히 판단하지 않으므로 주의 해야한다!

✏️ Youtuber demo 예외 고도화

  • youtuber-demo.js 파일도 예외처리 해서 고도화 해보자

  • 전체 조회 수정

// youtuber-demo.js

// 전체 조회
app.get("/youtubers", function(req, res){
	let youtubers = {};
	
	if(db) {
		db.forEach((value, index) => {
			youtubers[index] = value;
		});
		res.json(youtubers);
	} else {
		res.status(404).json({
			message : "조회할 유튜버가 없어요"
		})
	}
})

전체데이터 삭제후,

빈 객체와 200 OK 상태코드를 확인 할 수 있다.

why?

콘솔창을 db에 찍어보면, Map에 객체가 있는 것을 알 수 있다. 그런데 객체가 있지만, 안의 요소 갯수는 0일 뿐!

콘솔창

따라서, if문을 수정해준다.
- if(db) -> if(db.size !== 0)

   ...
   if(db.size !== 0) {
           db.forEach((value, index) => {
               youtubers[index] = value;
           });
           res.json(youtubers);
   } ...

그리고나서, 다시 전체 조회하면

이 말은,
❗️ 중요 : MAP은 아무리 안에 요소가 없어도 undefined 되지 않는 다는 것!!!

  • 개별 조회 수정
app.get('/youtubers/:id', function(req, res) {
	let {id} = req.params.id;
	id = parseInt(id);
	
	const youtuber = db.get(id);
	if(youtuber) {
		res.josn(youtuber)
	} else {
		res.status(404).json({
			message : `유튜버 정보를 찾을 수 없습니다`
		})
	}
})

  • 전체 삭제 수정
db.delete('/youtubers', function(req, res) {
	if(db.size >= 1) {
		db.clear();
		res.json({
			message: "전체 유튜버가 삭제되었어요"
		})
	} else {
		res.status(404).json({
			message: "삭제할 유튜버가 없어요"
		})
	}
})

  • 개별 삭제 수정
app.delete('/youtubers/:id', function(req, res) {
	let {id} = req.params;
	id = parseInt(id);
	
	const youtuber = db.get(id);
	if(youtuber) {
		const name = youtuber.channelTitle;
		db.delete(id);
		res.json({
				message: `$name}님, 다음에 또 봐요!`
		})
	} else {
		res.status(404).json({
			message: `${id}번은 가입된 유튜버가 아니에요`
		})
	}
})

  • 수정을 수정
app.put('/youtubers/:id', function(req, res) {
	let {id} = req.params;
	id = parseInt(id);
	
	const youtuber = db.get(id);
	if(youtuber) {
		const oldTitle = youtuber.channelTitle;
		const newTitle = req.body.channelTitle;
		
		youtuber.channelTitle = newTitle;
		db.set(id, youtuber);
		res.json({
			message: `${oldTitle}님, 채널명이 ${newTitle}로 변경 되었어요`,
		})
	} else {
		res.res(404).json({
			message : `${id}번은 없는 유튜버에요`
		})
	}
})

  • 등록 수정
    : POST의 예외는 body에 아무런 값도 넣지 않을 때이다. 예를 들어, channelTitle을 넣지 않고 보내면, undefined로 나오고 200 OK 상태 코드를 보여준다. 이렇게 되면, 오류가 났는지 알 수 없으므로 예외처리를 해야한다
app.post('/youtubers', function(req, res) {
	const channelTitle = req.body.channelTitle;
	if(channelTitle) {
		db.set(id++, req.body);
		res.status(201).json({
			message: `${db.get(id - 1).channelTitle}님, 유튜브 가입을 환영합니다`
		})
	} else {
		res.status(400).json({
			message: `요청값을 다시 보내주세요`
		})
		// 400코드 : 서버가 요청의 구문을 인식하지 못한 상태
		// 요청한 연산(처리)을 할 때 필요한 데이터(req)가 덜 왔을 때
		// 400번대 코드 : 클라이언트(사용자) 잘못
		// 500번대 코드 : 서버 잘못 (서버가 죽었을때)
		// 200번대 코드 : 성공 (등록성공: 201 // 조회/수정/삭제 성공: 200))
	}
})

✏️ 프로젝트 시작

  • 필요한 API들은 무엇이 있을까?

    • 회원
      • 로그인
      • 회원 가입
      • 회원 정보 조회
      • 회원 탈퇴
    • 채널
      • 채널 생성
      • 채널 수정
      • 채널 삭제
  • API를 설계할때는 화면을 대강 그려보면 설계하는 것이 편함

    • 로그인

      • 화면 생성시 : X
      • 필요한 API : 로그인 버튼 클릭시 -> id, pwd 받아와서 로그인 시켜줌
    • 회원 가입

      • 화면 생성시 : X
      • 필요한 API : 회원 가입 버튼 클릭시 -> id, pwd, name 받아와서 회원 가입 시킴
    • 회원 탈퇴

      • 화면 생성시 : 회원 정보 조회 API
      • 필요한 API : 회원 탈퇴 버튼 클릭시 -> 회원 탈퇴 시킴

✏️ 회원 API 설계

  • 로그인 POST /login

    • req : (body) id, pwd
    • res : ${name}님 환영합니다 + 메인 페이지
  • 회원 가입 POST /join

    • req : (body) userId, name, pwd
    • res : ${name}님 환영합니다 + 로그인 페이지
  • 회원 정보 조회 GET /users/:id (개별 조회)

    • req : (url) id
    • res : userId, name
  • 회원 탈퇴 DELETE /users/:id (개별 삭제)

    • req : (url) id
    • res : ${name}님 탈퇴되었습니다 or 메인 페이지

*body가 필요하면 POST임!!
설계는 더 나은 방법이 있다면 언제든 고칠 수 있고, 언제든 바꿀 수 있음!

✏️ 회원 API 코드 틀

: 이제 만들어보자.

  • npm init
  • npm install express
  • localhost:7777 접속 -> Cannot GET / 확인 : 서버 정상 작동
// user-demo.js

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

app.listen(7777);

// 설계 화면 보고 코드 작성

// 로그인
app.post('/login', function(req, res){
	
})

// 회원 가입
app.post('/join', function(req, res) {
	
})

// 개별 조회
app.get('/users/:id', function(req, res) {
	
})

// 개별 삭제
app.delete('/users/:id', function(req, res) {
	
})

✏️ 회원 가입 구현

// user-demo.js

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

app.listen(7777);
app.use(express.json()) // http 외 'json모듈' 사용 설정
// body값을 json으로 꺼내 쓸거임

let db = new Map();
let id = 1; // 하나의 객체를 구별하기 위함(중복 회원 가입 방지를 위해)

// 회원 가입
app.post('/join', function(req, res) {
	console.log(req.body)
	db.set(id++, req.body)
})

db에 데이터를 담고, POSTMAN : POST + localhost:7777/join + body(raw/json): { “userId” : “userId1”, “password” : 1234, “name” : “user1” }

콘솔창 확인하면,

그리고 셋팅

app.post('/join', function(req, res) {
	console.log(req.body);
	db.set(id++, req.body);
	res.satus(201).json({
		message : `${db.get(id-1).name}님 환영해요!`
		// db에 넣고 하나 올라가므로 1 뺴야함
})

다시 예외처리

  • 그런데, if문의 req.body에 아무것도 받아오지 않는다면 undefined값을 받아올 수 있음
    따라서, 방법은
  1. req.body == {} 를 넣거나
  2. req.body.size == 0 입력
app.post("/join", function (req, res) {
  if (req.body == {}) {
  	res.status(400).json({
      message: `입력값을 다시 보내주세요`,
    });
  } else {
  	db.set(id++, req.body);
    res.status(201).json({
      message: `${db.get(id - 1).name}님 환영해요!`,
    });
  }
});

✏️ 회원 개별 조회, 회원 개별 삭제

// 개별 조회
app.get('/users/:id', function(req, res) {
	let {id} = req.params;
	id = parseInt(id);
	const user = db.get(id);
	if(user) {
		res.status(200).json({
			userId : user.userId,
			name : user.name
		})
	} else {
		res.status(404).json({
			message: `회원 정보가 없어요`
		})
	}
})

// 개별 삭제
app.delete('/users/:id', function(req, res) {
	let {id} = req.params;
	id = parseInt(id);
	const user = db.get(id);
	if(user) {
		db.delete(id);
		res.status(200).json({
			message: `${user.name}님 다음에 또 뵐게요!`
		})
	} else {
		res.status(404).json({
			message: `회원 정보가 없어요`
		})
	}
})

개별 조회(등록하고, 개별 조회)

개별 삭제

✏️ 중복된 url 간단하게 바꾸기

app
	.route('/users/:id') // 이런 url에 날라오면 아래로 분기해서 사용할 수 있음
	.get( // 콜백함수 넣어야함
			function(req, res) {
				const {id} = req.params;
				id = parseInt(id);
				const user = db.get(id);
				if(user) {
					res.status(200).json({
						userId : user.userId,
						name : user.name
					})
				} else {
					res.status(404).json({
						message: `회원 정보가 없어요`
					})
				}
			}
	)
	.delete(
		function(req, res) {
			const {id} = req.params;
			id = parseInt(id);
			
			const user = db.get(id);
			if(user) {
				db.delete(id);
				res.status(200).json({
					message: `${user.name}님 다음에 또 뵐게요!`
				})
			} else {
				res.status(404).json({
					message: `회원 정보가 없어요`
				})
			}
		}
	)

이번엔 예외처리를 해서 같은 결과가 나오는지 보자

🍎🍏 오늘의 느낀점

오늘 강의는 정말 길었다.. 따라하면서 하다보니 그랬나..? 무튼 youtuber-demo의 예외처리 고도화도 시켜보고, 본격적으로 API를 설계하기 위한 준비, 구상들을 실제로 해보면서 API까지 직접 적고 확인해보니 재밌기도 하고 아직 익숙하지 않아서 헷갈리기도 했다. 그래도 익숙해지면 괜찮을 것 같다! 다만, 나중에 프론트엔드에게 어떤 방식으로 전해줄지는 다음 수업 때 알 수 있을 것 같다. 그리고 오늘 map은 무조건 빈 객체값을 반환하는 것도 알게 되어서 size값을 넣어 처리해 주는 지식도 하나 더 알게 되어서 기쁘다..! 점점 많이 연습하다보면 익숙해지겠지?!?!

profile
프론트엔드개발자가 되고 싶어서 열심히 땅굴 파는 자

0개의 댓글