- 소개
- 시작하기
- 철학
- 비교
- 제한 사항
- 디버깅 실행 매뉴얼
- FAQ
- Basics
- Concepts
- Network behavior
- Integrations
- API
- CLI
- Best practices
- Recipes
- Cookies
- Query parameters
- Response patching
- Polling
- Streaming
- Network errors
- File uploads
- Responding with binary
- Custom worker script location
- Global response delay
- GraphQL query batching
- Higher-order resolver
- Keeping mocks in sync
- Merging Service Workers
- Mock GraphQL schema
- Using CDN
- Using custom "homepage" property
- Using local HTTPS
요청 가로채기
나가는 요청을 가로채는 방법을 배워보세요.
요청에 대해 모의 응답을 보내려면 먼저 해당 요청을 가로채야 합니다. Mock Service Worker에서 요청 가로채기는 요청 핸들러 라는 함수를 통해 수행됩니다.
요청 핸들러 함수는 다음과 같이 생겼습니다:
// 경로가 "predicate"와 일치하는 HTTP GET 요청을 가로채고
// 주어진 "resolver" 함수를 사용해 해결합니다.
http.get(predicate, resolver)
// GraphQL 뮤테이션에 대한 유사한 요청 핸들러
graphql.mutation(predicate, resolver)
요청 핸들러에 대해 더 알아보세요.
이 페이지에서는 resolver
부분을 생략하고, 요청 핸들러가 어떻게 요청 가로채기를 가능하게 하는지에 초점을 맞출 것입니다. 요청 가로채기 방식은 모의로 만들려는 API 타입에 따라 달라지며, 해당 API의 도메인 언어를 반영합니다.
HTTP 요청
HTTP 요청은 http
요청 네임스페이스를 사용하여 가로챌 수 있습니다. 이 네임스페이스의 메서드는 HTTP 메서드를 나타내며 (http.get()
, http.post()
등), 두 개의 인자를 받는 동일한 함수 호출 시그니처를 가지고 있습니다:
predicate
(string | RegExp
), 요청 경로 조건;resolver
, (Response resolver
), 가로챈 요청을 처리하는 방법을 결정하는 함수.
예를 들어, 다음은 GET /pets
요청에 대해 애완동물 목록을 반환하는 요청 핸들러입니다:
import { http, HttpResponse } from 'msw'
http.get(
// "/pets" 문자열은 경로 조건입니다.
// 경로가 "/pets" 문자열과 일치하는 GET 요청만 가로챕니다.
'/pets',
// 아래 함수는 "resolver" 함수입니다.
// 가로챈 요청에 대한 정보를 받아 처리 방법을 결정합니다.
({ request, params, cookies }) => {
return HttpResponse.json(['Tom', 'Jerry', 'Spike'])
}
)
http
요청 네임스페이스에 대해 더 알아보세요.
HTTP 요청 매칭
predicate
인자를 사용하면 여러 기준으로 HTTP 요청을 가로챌 수 있습니다. 요청 조건을 작성하는 모든 가능한 방법을 자세히 살펴보겠습니다.
요청 경로명
predicate
인자가 문자열일 때, 해당 문자열과 경로명이 일치하는 요청만 가로챌 수 있습니다. 이는 상대 URL과 절대 URL 모두 동일하게 작동합니다!
export const handlers = [
http.get('/pets', petsResolver),
http.post('https://api.github.com/repo', repoResolver),
]
상대 요청 URL은 현재 location.origin
을 기준으로 해석됩니다.
여러 요청을 동시에 가로챌 수 있도록 요청 조건 문자열에 특수 토큰을 포함할 수 있습니다. 가장 일반적인 토큰 중 하나는 와일드카드 (*
)로, 해당 위치의 모든 문자열과 일치합니다:
// "/user"로 시작하는 모든 GET 요청을 가로챕니다:
// - GET /user
// - GET /user/abc-123
// - GET /user/abc-123/settings
http.get('/user/*', userResolver)
MSW의 요청 경로명 매칭은
path-to-regexp
라이브러리를 사용합니다. 지원되는 모든 경로 토큰에 대해 더 알아보려면 해당 문서를 참고하세요.
요청 경로명을 제공할 때는 _쿼리 매개변수를 제외_해야 합니다. 쿼리 매개변수는 리소스 식별에 영향을 미치지 않으며, 서버에 추가 정보를 보내는 수단으로 사용됩니다. MSW가 쿼리 매개변수를 발견하면 이를 제거하고, 여러분도 제거해야 한다는 경고를 출력합니다. 쿼리 매개변수의 값은 여전히 응답 리졸버의 request.url
속성에서 확인할 수 있습니다.
정규 표현식
요청 경로 조건자로 정규 표현식을 사용할 수 있습니다. 제공된 표현식과 URL이 일치하는 요청만 가로챌 수 있습니다. 정규 표현식의 동적 특성을 활용하여 더 복잡한 요청 매칭 시나리오를 처리할 수 있습니다.
// 정규 표현식과 일치하는 DELETE 요청을 가로챕니다.
// - DELETE /settings/sessions
// - DELETE /settings/messages
http.delete(/\/settings\/(sessions|messages)/, resolver)
GraphQL API 요청
GraphQL 서버는 주로 HTTP를 통해 구현되므로, 동일한 http
요청 네임스페이스를 사용하여 이를 가로채고 처리할 수 있습니다. 하지만 MSW는 전용 graphql
요청 네임스페이스를 사용하여 GraphQL API를 가로채는 퍼스트클래스 지원을 제공합니다. 이 네임스페이스의 메서드는 GraphQL 작업 타입(graphql.query()
, graphql.mutation()
)을 나타내며, 다음과 같은 인자를 기대하는 동일한 함수 호출 시그니처를 가지고 있습니다:
predicate
, (string | RegExp | TypedDocumentNode
);resolver
, (Response resolver
).
예를 들어, ListPets
쿼리에 대한 요청 핸들러는 다음과 같이 작성할 수 있습니다. 이 핸들러는 애완동물 목록을 반환합니다:
import { graphql, HttpResponse } from 'msw'
export const handlers = [
graphql.query('ListPets', () => {
return HttpResponse.json({
data: {
pets: [
{ id: 1, name: 'Tom' },
{ id: 2, name: 'Jerry' },
{ id: 3, name: 'Spike' },
],
},
})
}),
]
GraphQL 요청 매칭
기본적으로 MSW는 모든 GraphQL 요청을 operation type 과 operation name 에 따라 매칭합니다. 이를 쉽게 이해하려면 애플리케이션이 보내는 실제 GraphQL 쿼리를 상상해 보세요:
query ListPets {
pets {
id
name
}
}
위 쿼리에서 query
는 operation type이고 ListPets
는 operation name입니다.
이제 GraphQL 요청 조건을 정의하는 모든 방법을 살펴보겠습니다.
GraphQL operation name
GraphQL 요청 조건이 문자열일 때, 해당 문자열과 이름이 일치하는 작업만 가로챕니다.
// 제공된 이름과 일치하는 GraphQL 쿼리를 가로챕니다.
// - "query GetUser { ... }"
graphql.query('GetUser', userResolver)
정규 표현식_9q7htiLXWrQ3gciLMm7MUZ
HTTP 요청 매칭과 유사하게, 정규 표현식을 사용하여 어떤 GraphQL 작업 이름을 가로챌지 더 세밀하게 제어할 수 있습니다.
// 정규 표현식과 일치하는 GraphQL 뮤테이션을 가로챕니다.
// - "mutation CreateUser { ... }"
// - "mutation CreateAuthor { ... }"
graphql.mutation(/(CreateUser|CreateAuthor)/, resolver)
엔드포인트 URL
더 복잡한 시나리오에서는 특정 HTTP 엔드포인트에 바인딩하여 GraphQL 요청을 가로챌 수 있습니다. 이는 애플리케이션 내에서 서로 다른 GraphQL API에 대해 동일한 작업 타입/이름을 구별해야 할 때 특히 유용합니다.
import { graphql } from 'msw'
const github = graphql.link('https://api.github.com/graphql')
const stripe = graphql.link('https://api.stripe.com')
export const handlers = [
github.query('GetUser', githubUserResolver),
stripe.query('GetUser', stripeUserResolver),
]
graphql.link()
API에 대해 더 알아보세요.
Common questions
Node.js에서 상대 URL을 어떻게 사용하나요?
사용하지 않습니다. Node.js에서는 상대적으로 참조할 대상이 없습니다. Node.js 애플리케이션의 네트워크 동작을 설명한다면, 요청하는 절대 URL을 사용하세요. Jest나 Vitest 같은 Node.js 기반 테스트 러너와 함께 MSW를 사용한다면, 상대 URL을 지원하도록 해당 러너를 설정하세요(예: document.baseURI
문자열을 폴리필).