티스토리 뷰

개발공부/🟩 Node.js

[NodeJS] Express.js로 REST API 구현하기

2022. 7. 30. 01:32

 

 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

 

 

 

 REST API 

 

▶ REST API 란?

 

REST + API

:  REST 아키텍쳐를 준수하는 웹 API

(RESTful API라고 부르기도 함)

 

-  API (Application Programming Interface)

:  서비스나 프로그램 간에 미리 정해진 기능을 실행할 수 있도록 하는 규약

 

- REST (REpresentational State Transfer)

:  웹에서 자료를 전송하기 위한 표현 방법에 대한 아키텍쳐.

이미지출처 : 엘리스 Node.js와 MongoDB Ⅰ - 04 Express.js와 REST API 강의자료

 

 

 

 

 

▶ REST API 기본 가이드

 

REST를 정확하게 구현하기 위해서는 많은 제한조건이 있지만,

'URL을 통한 자원의 표현방법'과 'HTTP method를 통한 API 동작의 정의' 정도만 사용해도 훌륭한 REST API를 구현 가능

 

1)  HTTP Method의 사용

:  REST API는 API의 동작을 HTTP method + 명사형 URL로 표현

→ HTTP method(GET, POST, PUT, DELETE) 와 결합하여 API 동작을 정의

 

2)  URL 표현법

:  REST API URL의 자원은 복수형으로 표현

하나의 자원에 대한 접근은 복수형+아이디 를 통해 특정 자원에 접근

(ex.  '/posts' 가 '게시글 전체'를 칭하는 URL이면, '/posts/1' 은 '1번 게시글'이라는 자원을 표현)

 

3)  계층적 자원

:  REST API는 URL을 통해 자원을 계층적으로 표현

(ex.  '/users/1/posts' 라는 URL은 '1번 유저의 게시글 전체'라는 자원을 표현)

 

 

 

 

 

 

 JSON 

 

▶ JSON 이란?

 

JavaScript Object Notation  :  자바스크립트에서 객체를 표현하는 표현식

→  데이터를 표현하는 방법이 단순하고 이해하기 쉬워 웹 API에서 데이터를 전송할 때 표현식으로 주로 사용

 

-  웹 API는 기본적으로 데이터를 문자열로 전송  →  어떤 객체를 웹 API를 통해 문자열로 전달하기 위해 JSON을 사용

 

 

 

JSON  vs.  XML

 

-  JSON이 더욱 적은 표현식을 사용하여 데이터를 효과적으로 표현 가능

// animals.json
[
    { name: 'cat', legs: 4 }, 
    { name: 'chicken', legs: 2 },
]



// animals.xml
<array>
    <item>
        <name>cat</name>
        <legs>4</legs>
    </item>
    <item>
        <name>chicken</name>
        <legs>2</legs>
    </item>
</array>

 

 

 

▶ JSON 가이드

 

1)  Object 는 { "key": value } 로 표현

- value 에는 어떤 값이라도 사용 가능 (문자열, 숫자, JSON 객체 등)

 

2)  Array는 [item1, item2] 로 표현

- item에는 어떤 값이라도 사용 가능 (문자열, 숫자, JSON 객체 등)

 

 

 

 

 

 

  Express.js로 REST API 구현하기 

 

▶ MVC 패턴

 

Model-View-Controller 를 구분하여 프로젝트 구조를 구성.

웹 서비스의 가장 대표적인 프로젝트 구성 패턴으로 프로젝트의 기능들을 어떻게 분리할지에 대한 하나의 구성 방법

 

 

Model

:  데이터에 접근하는 기능 또는 데이터 그 자체를 의미

→  데이터의 읽기, 쓰기는 Model을 통해서만 이루어지도록 구성해야함

 

View

:  데이터를 표현하는 기능

→ 주로 Controller 에 의해 데이터를 전달받고 전달받은 데이터를 화면에 표시하는 기능을 담당

 

Controller 

:  Model 을 통해 데이터에 접근하여 처리결과를 View로 전달하는 기능

→  웹 서비스에선 주로 라우팅 함수가 해당 기능을 수행

 

 

 

 

▶ 예제 구현하기

 

1)  메모 목록 구현

// models/note.js

let notes = [			// 메모가 담기는 목록
    { 
        id: 1, 
        title: 'first note', 
        content: 'My first note is here.'
    }
];

exports.list = () => {		// 메모목록(notes)안에서 id와 title만 가져와 새로운 목록 생성
    return notes.map(({ id, title }) => ({
        id,
        title,
    }));
}
// routes/notes.js

const { Router }= require('express');
const Note = require('../models/note');

const router = Router();

router.get('/', (req, res, next) => {
    const notes = Note.list();		// note목록을 받아와
    res.json(notes);			// res에 json으로 전달
});

 

 

2)  메모 상세 구현

// models/note.js

exports.get = (id) => {
    const note = notes.find(		// note목록 안에 전달받은 id와 동일한 값이 있는지 찾기
        (note) => note.id === id		
    );
    
    if (!note) {
    	throw new Error('Note not found');
    }
    
    return note;
}
// routes/notes.js

router.get('/:id', (req, res, next) => {	// path parameter로 '/:id'를 갖도록
    const id = Number(req.params.id);
    
    try {
        const note = Note.get(id);
        res.json(note);
    } catch (e) {
    	next(e);
    }
});

 

 

3)  메모 작성 구현

// models/note.js

exports.create = (title, content) => {
    const { id: lastId } = notes[notes.length - 1];	// 메모목록 중 가장 마지막 메모의 id를 lastId라는 변수로 destructing
    
    const newNote = { 		// 새로운 메모 생성
        id: lastId + 1, 
        title, 
        content,
    };
    
    notes.push(newNote);
    return newNote;
}
// routes/notes.js

router.post('/', (req, res, next) => {
    const { title, content } = req.body;
    const note = Note.create(title, content);
    res.json(note);
});

 

 

4) 메모 수정 구현

// models/note.js

exports.update = (id, title, content) => {
    const index = notes.findIndex((note) => note.id === id);	// .findIndex() : 조건에 맞는 요소를 찾아서 그 요소의 index를 반환
    
    if (index < 0) {
    	throw new Error('Note not found for update');
    }
    
    const note = notes[index];
    note.title = title;
    note.content = content;
    notes[index] = note;
    
    return note;
}
// routes/notes.js

router.put('/:id', (req, res, next) => {
    const id = Number(req.params.id);
    const { title, content } = req.body;
    
    try {
        const note = Note.update(id, title, content);
        res.json(note);
    } catch (e) {
        next(e);
    }
});

 

 

5)  메모 삭제 구현

// models/note.js

exports.delete = (id) => {
    if (!notes.some((note) => note.id === id)) {	// .some() : 조건에 맞는 요소가 있는지 찾아서 true, false 반환
        throw new Error(
        	'Note not found for delete'
        );
    }
    
    notes = notes.filter(note => note.id !== id);	// 삭제하려는 메모를 제외한 메모목록 생성
    return;						// .filter() : 조건이 참인 요소만 남김. 여기서는 삭제하려는 id와 같지않은 id의 메모들만 남기는것
}
// routes/notes.js

router.delete('/:id', (req, res, next) => {
    const id = Number(req.params.id);
    
    try {
        Note.delete(id);
        res.json({ result: 'success' });
    } catch (e) {
        next(e);
    }
});

 

 

6)  JSON 데이터 처리 미들웨어 사용

 

express.js 는 기본적으로 HTTP body에 전달되는 JSON 데이터를 처리하지 못함

→  express 에서 기본적으로 제공해주는 express.json() 미들웨어를 사용

// index.js

app.use(express.json());

 

 

7)  오류 처리 미들웨어 구현

// index.js

app.use((err, req, res, next) => {
    res.status(500);
    res.json({
        result: 'fail',
        error: err.message,
    });
});

 

 

8)  정의되지 않은 라우팅에 404오류 처리

 

-  모든 라우팅이 적용된 이후에 사용되는 미들웨어는 설정된 경로가 없는 요청을 처리하는 Route Handler로 동작

-  Express.js 는 기본적으로 404페이지를 가지고 있지만 직접 처리가 필요한 경우 추가 가능

// index.js

app.use((req, res, next) => {
    res.status(404);
    res.send({ 
        result: 'fail', 
        error: `Page not found ${req.path}`
    });
});

 

 

 

 

 

▶ Postman 사용하기

 

-  Postman 은 API를 테스트할 수 있는 도구

-  HTTP 요청을 쉽게 작성하여 테스트 가능

-  API 를 문서화할 수 있는 기능 및 다양한 도구 제공

 

 

Postman 으로 API 문서화하기

:  collection 만들기  →  api request 만들기  →  document 작성하기  →  전체 문서 확인하기

 

1)  Postman 설치 후 회원가입

 

 

2)  Workspace 생성

:  기본적으로 My Workspace가 지정되어 있음

 

 

3)  Workspace 들어와서 Collections 생성

→  좌측 Collections 탭에서  + 버튼을 클릭하여 새 Collection 생성  →  컬렉션 이름 설정

 

 

4)  우측에 Documentation에 작성

 

5)  Collections 하위에 request 추가

→  request 추가하려면 Collection 이름 좌측 ... 버튼 클릭하여 Add request 클릭

 

 

6)  각 request마다 Documentation 작성

(ex.  메모 목록 request는 '메모 목록 API 입니다.' 작성)

 

→  작성한 Documentation 보려면 Collection 이름 좌측 ... 버튼 클릭하여 View documentation 클릭

 

 

 

Postman 으로 API 테스트하기

:  HTTP Method 설정하기  →  query param 사용하기  →  path variable 사용하기  →  body 사용하기

 

1) 커미널에서 작성한 메모 API 프로젝트 실행    npm start 

 

2)  메모 목록 request 에서 'GET / localhost:3000/notes' Send 한 후 저장

→  Documentation 에 추가됨

 

 

3)  localhost 같이 반복되는 값은 변수로 만들어서 사용

→  Collection 이름 좌측 ... 버튼 클릭하여 Edit 클릭  →  Variables 클릭

→  variable에 변수 이름, value에 변수 값 입력 후 저장

→  변수의 사용은 변수명을 대괄호 2개로 감싸서 사용  :  {{변수명}}

 

 

4) 각 request 마다 위의 2)처럼 url 저장 반복

 

- 메모 상세  :  'GET   /   {{HOST}}/notes/:id'  →   ':/id'는 path parameter

→  Path Variables 생성되면 key와 value 설정 후 전송 가능

 

 

- 메모 생성  :  'POST   /   {{HOST}}/notes'

→ 메모 생성 시에는 Body 를 사용  →  Body 클릭 후 raw 에서 JSON으로 설정

→  JSON으로 값 입력하여 Send 후 저장

- 메모 수정  :  'PUT   /   {{HOST}}/notes/:id'

 

- 메모 삭제  :  'DELETE   /   {{HOST}}/notes/:id'

 

 

5)  요청을 보냈을 때의 응답을 Save Response로 저장 가능

→  Save Response 에서 Save as example 클릭

→  이름 변경해주고 저장하면 좌측 collection 에 응답이 추가됨

→  전체 Documentation 가보면 Example 이 추가되어있는 것을 확인 가능

 

 

 

 


 이 글은 엘리스 AI트랙 5기 강의를 들으며 정리한 내용입니다.

반응형

'개발공부 > 🟩 Node.js' 카테고리의 다른 글

[NodeJS] Mongoose ODM  (0) 2022.07.31
[NodeJS] Node.js와 MongoDB  (0) 2022.07.31
[NodeJS] Express.js의 Middleware  (0) 2022.07.28
[NodeJS] 웹과 Express.js  (0) 2022.07.27
[NodeJS] NPM과 모듈  (0) 2022.07.27
프로필사진
개발자 삐롱히

프론트엔드 개발자 삐롱히의 개발 & 공부 기록 블로그