front-end/msw

[MSW] Describing REST API

Ash_O 2024. 1. 19. 19:40

Import

MSW는 HTTP 요청을 설명하기 위한 별도의 네임스페이스를 제공한다

이 네임스페이스로 가로챌 요청과 그에 대한 응답 방법을 설명한다

import the http namespace from the msw package

src/mocks/handlers.js

import { http } from 'msw'

export const handlers = []

Request handler

이제 Request handler를 만든다.

http namespace의 모든 메서드는 HTTP 요청 메서드에 대응되는 요청 핸들러를 만들게한다.

http[method](predicate, resolver)

Request handler : 요청과 mock 응답을 가로채게 하는 함수

실습 endpoint

  • GET /posts : 모든 게시글 반환
  • POST /posts : 새로운 게시글 생성
  • DELETE /post/:id : ID에 해당하는 게시글 삭제

예시1

import { http } from 'msw'

export const handlers = [
	// http.get() 을 호출함으로써, msw에게 "GET /posts" 로 나가는 모든 요청을 가로채도록 지시하고
	// 이런 요청이 발생할 때 주어진 응답 resolver를 실행하도록 한다
	http.get('/posts', () => {
		// 응답 resolver를 사용하면 가로챈 요청에 대응하여 모의 응답을 반환하거나 요청을 통과시킬 수 있다.
		// 지금 코드는 console.log
		console.log('Captured a "GET /posts" request')
	}),
]

예시2

// src/mocks/handlers.js
import { http } from 'msw'
 
export const handlers = [
  http.get('/posts', () => {
    console.log('Captured a "GET /posts" request')
  }),
  http.post('/posts', () => {
    console.log('Captured a "POST /posts" request')
  }),
  http.delete('/posts/:id', ({ params }) => {
    console.log(`Captured a "DELETE /posts/${params.id}" request`)
  }),
]

이 핸들러들이 정의되면, msw는 각 요청을 가로챌것이지만, 아직 어떤 응답도 하진 않을거다

Response resolver

Response resolver는 가로챈 요청을 다루는 방법을 결정하는 요청 핸들러의 두번째 인자이다

요청으로 할수 있는 것들

  • mock response 응답하기
  • as-is 수행하기
  • porxy 요청 수행하기
  • 원본 응답 확장하기
  • 등..

실습 : Mock responses

Mocking responses

가로챈 요청에 응답하기 위해, 유효한 Fetch API Response 인스턴스를 구축하고 대응하는 요청 핸들러에서 반환해야한다.

Response 인스턴스를 직접 작업할 수 있지만, MSW에서는 HttpResponse 를 사용하는걸 추천한다고한다

import { http, HttpResponse } from 'msw'

그리고, 모든 게시글 리스트를 반환하기 위한 모의 응답을 구축하자

import { http, HttpResponse } from 'msw'

// 메모리에 있는 모든 게시글의 map
// 시작은 빈 배열 ( 게시글이 없으니까 )
const allPosts = new Map()

export const handlers = [
	http.get('/posts', () => {
		// Response body로서 모든 게시글의 리스트로 JSON 응답을 구축한다
		return HttpResponse.json(Array.from(allPosts.values()))
	}),

	// 다른 요청 핸들러들
]

HttpResponse.json() 메서드를 사용하면, 이 resolver에서 반환되는 모의 응답은 application/json 형식의 응답이 된다.

Reading request body

POST /posts 핸들러에서는, request body를 읽고 allPosts 맵에 새로운 포스트를 넣을거다

응답 resolver 함수에 전달된 request 인자를 사용해서 가로챈 요청 인스턴스에 대한 참조를 얻을 수 있다.

// src/mocks/handlers.js
import { http, HttpResponse } from 'msw'

const allPosts = new Map()

export const handlers = [
	http.post('/posts', async ({ request }) =>{
		// 가로챈 요청 바디를 JSON으로 읽기
		const new Post = await request.json()

		// 새로운 게시글을 맵에 넣기
		allPosts.set(newPost.id, newPost)

		// 의미론적으로 "201 Created" 응답을 선언하고, 다시 돌려주는 부분
		return HttpResponse.json(newPost, { status: 201 })
	}),
]

Reading path paramerters

마지막으로, DELETE /post/:id resolver 구현이다.

ID에 해당하는 게시글을 allPost에서 찾아서 없애는 기능

요청 URL의 path parameter는 response resolver 함수에 params 인자로 파싱되고 저장된다.

import { http, HttpResponse } from 'msw'

const allPosts = new Map()

export const handlers = [
	http.delete('/posts/:id', ({ params }) => {
		// 모든 요청 path params는 response resolver의 params 인자에 전달된다
		const { id } = params

		// id에 대응하는 게시글 추출하기
		const deletedPost = allPosts.get(id)

		// 주어진 게시글 id가 존재하지 않는다면 "404 Not Found" 를 응답한다
		if (!deletedPost) {
			return new HttpResponse(null, { status: 404 })
		}
	
		// allPosts 맵에서 게시글 삭제하기
		allPosts.delete(id)

		// 삭제된 게시글과 함께 "200 OK" 응답 보내기
		return HttpResponse.json(deletedPost)
	}),
]

response resolver는 가로챈 요청에 대해 유용한 정보를 제공해준다

  • request cookies
  • GraphQL query and variable
  • 등등

Reading request cookies

요청의 Cookie 헤더의 파싱된 값을 응답 resolver 객체 인수의 cookies 키로 접근하기

http.get('/user', ({ cookies }) => {
	const { session } = cookies

	if (!session) {
		return new HttpResponse(null, { status : 401 })
	}
})

'front-end > msw' 카테고리의 다른 글

[MSW] 브라우저 환경에서 사용하기  (0) 2024.01.19
[MSW] Mock Service Worker - Basic 번역  (0) 2024.01.09