3. Westagram Endpoint 구현⭐️_10.26

송철진·2023년 1월 12일
0

Simple API server with http module(3)

3. Westagram Endpoint 구현

3-1. ping 엔드포인트 구현하기

엔드포인트 : API 서버가 제공하는 통신 채널, 접접.

ping 엔드포인트

  • http:127.0.0.1/ping의 URL로 요청을 보냈을 때, 서버가 정상적으로 실행되고 있다면, "pong"이라는 텍스트를 반환하는 엔드포인트
  • API 서버에 접속하지 않고 해당 API가 정상적으로 운행하고 있는지 여부를 확인(health check)

클라이언트는 백엔드 API 서버와 엔드포인트에 접속하는 형태로 통신한다.
고유 URL 주소를 통해 해당 엔드포인트에 요청을 보낼 수 있다.
고유의 기능을 담당하는 각 엔드포인트가 모여서 하나의 API를 구성한다.

  • 크롬 브라우저(Client)
  • Httpie(개발용 Client)

start line

GET /ping HTTP/1.1
  • 요청 메세지의 최상단 라인
  • http method. 해당 엔드포인트에 요구하는 액션
    • GET: 받아와, POST: 보내, DELETE: 삭제해
  • target. 요청을 실질적으로 처리하는 부분. 엔드포인트.

소스코드 이해하기

// app.js
const http = require('http');
const server = http.createServer();

const httpRequestListener = function (request, response) {
  const { url, method } = request  // (1)
	if (method === 'GET') { // (2)
		if (url === '/ping') { // (3)
			response.writeHead(200, {'Content-Type' : 'application/json'}); // (4)
			response.end(JSON.stringify({message : 'pong'}) // (5)
		}
	}
};
server.on("request", httpRequestListener);
server.listen(8000, '127.0.0.1', function() { 
    console.log('Listening to requests on port 8000');
});
  1. 실행중인 API server가 http request를 받는다.
  2. server 객체에 등록한 "request" 이벤트에 연결된 httpRequestListener가 실행된다.
const http = require('http');
const server = http.createServer();

server.on("request", httpRequestListener);
  1. callback 함수 httpRequestListener의 인자로 request와 response 객체를 내부적으로 만들어 전달해준다.
  • request 객체에 http request message의 대부분의 정보가 할당됨.
const httpRequestListener = function (request, response) {
	// (1) ~ (5)
}
  1. (1) request 객체에서 url과 http_method 정보를 추출해 url, method 변수에 할당한다
const { url, method } = request // (1)
  1. request가 요청한 (2) http 메소드와 (3) target을 판별한다.
    (3) target이 /ping 이면 response 객체를 사용해서 클라이언트로부터 받은 요청에 보낼 응답 내용을 결정한다
if (method === 'GET') { // (2)
	if (url === '/ping') { // (3)
        // (4) ~ (5)
    }
}
  1. (4) response message의 body에 어떤 데이터 타입을 보낼지를 결정하는 header를 설정한다
response.writeHead(200, {'Content-Type' : 'application/json'}); // (4)
  1. (5) 인자의 값을 응답 메시지의 body에 담는 response.end() 함수를 호출해 클라이언트에게 http 응답을 보낸다
response.end(JSON.stringify({message : 'pong'}) // (5)

JSON.stringify()
인자의 값인 Javascript Object를 JSON화하는 모듈.

비지니스 로직(business logic)을 구현하는 함수들을 개발하는 것이 백엔드 API에서 가장 많은 부분을 차지한다

3-2. 회원가입 엔드포인트 구현하기

본래 인스타그램처럼 많은 동시 접속들을 빠르게 처리하는 시스템을 구현하려면
시스템 측면과 로직 구현 측면에서 많은 것들을 고려해야 한다.
(여기서는 많은 동시 접속과 HTTP 요청 처리 속도는 고려하지 않음)

회원가입 절차

사용자로부터 이름, 이메일, 비밀번호 등 회원 정보를 HTTP 요청을 통해 받은 후 시스템에 저장한다

id, name, email, password

회원가입 요청 메세지 / 응답 메세지

http -v POST http://127.0.0.1:8000/users/signup 
	id:=3 
    name='홍길동' 
    email='hong@gmail.com' 
    password='1q2w3e4r'

회원가입 엔드포인트 구현

  1. (1) ping 엔드포인트와 서버 구현
// app.js
const http = require('http'); // (1)
const server = http.createServer();

// (2)

const httpRequestListener = function (request, response) {
  const { url, method } = request
	if (method === 'GET') {
		if (url === '/ping') {
			response.writeHead(200, {'Content-Type' : 'application/json'});
			response.end(JSON.stringify({message : 'pong'}));
		}
	}
  	// (3) ~ (9)
}

server.on("request", httpRequestListener);

server.listen(8000, '127.0.0.1', function() { 
    console.log('Listening to requests on port 8000');
});
  1. 새롭게 회원가입 하는 사용자 정보를 저장할 배열을 변수 users에 정의한다. 배열 안에 객체 형태로 회원 정보가 저장될 것이다.
const users = [ // (2)
  {
    id: 1,
    name: "Rebekah Johnson",
    email: "Glover12345@gmail.com",
    password: "123qwe",
  },
  {
    id: 2,
    name: "Fabian Predovic",
    email: "Connell29@gmail.com",
    password: "password",
  },
]
  1. (3) request message에서 꺼내온 http method(POST), tartget(/users) 정보와 if문을 사용해서 엔드포인트를 정의한다.
else if (method === 'POST') { // (3)
	if (url === '/users') {
      // (4) ~ (9)
    }
}
  1. ,(4) (5) HTTP 요청을 통해 전송된 body에 담긴 회원 정보를 읽어 들인다.
  • 짧은 단위로 나누어져서 받아지는 body에 담겨있는 데이터를 하나로 합쳐서 body라는 변수에 정의.
let body = ''; // (4)
request.on('data', (data) => {body += data;}) // (5)

Event Driven Architecture

  1. (6) 데이터를 정상적으로 받아온 이후에 자동으로 실행. request.on() 함수에 인자로 전달한 arrow function이 실행됩니다.
// stream을 전부 받아온 이후에 실행
request.on('end', () => {  // (6)
  // (7) ~ (9)
})
  1. (7) JSON.parse()를 활용해서 HTTP 요청을 통해 전송된 JSON 데이터를 javascript object로 변환해 준다.
const user = JSON.parse(body); // (7) 
  1. (8) Client로부터 받은 사용자 정보를 객체 형태로 만들어서 users 배열에 추가해주면서, 회원 등록을 완료한다.
users.push({ // (8)
	id : user.id,
	name : user.name,
	email: user.email,
	password : user.password
})
  1. (9) 마지막으로 회원가입이 성공적으로 끝났음을 알리는 “ok!” 메세지를 응답으로 보내줍니다.
response.end(JSON.stringify({message : 'ok!'})); // (9)
http -v POST http://127.0.0.1:8000/users/signup 
id:=3 name='홍길동' email='hong@gmail.com' password='1q2w3e4r'

크리티컬 이슈
회원 정보를 users라는 배열에 저장한다는 것은 API가 실행되고 있는 서버의 메모리에 저장된다는 것! API 서버를 종료하고 다시 시작하면 users 배열에 저장되어 있는 모든 정보는 사라진다.
👉 데이터베이스가 필요한 이유

response.writeHead() 작성 전/후 비교

profile
검색하고 기록하며 학습하는 백엔드 개발자

0개의 댓글