A wrapper to use MSW in a type-safe manner for aspida users.
- Simple
- Type safe
- Aspida-like interface
npm install mswpida --save-dev
// 1. Create `typedHttp` from the `api` function generated by aspida.
import { createTypedHttp } from 'mswpida';
import api from './awesome/store/$api';
const typedHttp = createTypedHttp(api);
// 2. Write MSW's request handler using `typedHttp`.
import { HttpResponse } from 'msw';
const handlers = [
typedHttp.products._productId.images.$post(({ request, params }) => {
console.log(`Add an image to product ${params.productId}`); // Path parameter is typed ✅
const reqBody = await request.json();
console.log(`Image description: ${reqBody.description}`); // Request body is typed ✅
return HttpResponse.json(
{ id: 123, ...reqBody }, // Response body is also typed ✅
{ status: 201 },
);
}),
// ...
];
// 3. Subsequent usage is the same as the regular MSW usage.
import { setupWorker } from 'msw/browser';
// or
// import { setupServer } from 'msw/node';
await setupWorker(...handlers).start();
Creates a typedHttp
object based on the api
function generated by aspida. This typedHttp
is a wrapper to write MSW's request handler.
baseURL
(optional): Specifies the base URL for the API. Works the same as aspida'sbaseURL
option.
createTypedHttp(api, { baseURL: 'https://staging.example.com' });
An object for writing MSW's request handler. Essentially, it is a thin wrapper for MSW's http
. The usage is almost identical to http
, but paths and methods are expressed in an aspida-like format.
const handler = typedHttp.products._productId.images.$post(({ request, params }) => ...);
// This is equivalent to:
const handler = http.post('https://example.com/products/:productId/images', ({ request, params }) => ...);
Paths are expressed as properties. While path parameters are expressed with function calls like ._productId('abc123')
in aspida, note that in typedRest
, they are simply expressed as properties like ._productId
.
Use .$path()
to get the path of that endpoint as a string.
const path = typedHttp.products._productId.images.$path();
// -> 'https://example.com/products/:productId/images'
Expressed as the $
-prefixed HTTP method function, like .$get(resolver)
or .$post(resolver)
. The argument is MSW's response resolver. The following three are typed from aspida's api
, so no type annotations are required:
- Path parameters:
params
- As per MSW's behavior, the type of value is always
string
.
- As per MSW's behavior, the type of value is always
- Request body:
await request.json()
- Response body: the first argument of
HttpResponse.json()
const handler = typedHttp.products._productId.images.$post(
({ request, params }) => {
console.log(`Add an image to product ${params.productId}`); // Path parameter is typed ✅
const reqBody = await request.json();
console.log(`Image description: ${reqBody.description}`); // Request body is typed ✅
return HttpResponse.json(
{ id: 123, ...reqBody }, // Response body is also typed ✅
{ status: 201 },
);
},
);
By using method with a type parameter like .$get<T>()
or .$post<T>()
, you can return T
as the response body without getting a type error.
type ErrorResponseBody = { errorCode: string };
const handler = typedHttp.products._productId.images.$post<ErrorResponseBody>(
({ request, params }) => {
if (params.productId === 'bad_id') {
return HttpResponse.json(
{ errorCode: 'product_not_found' },
{ status: 404 },
);
}
const reqBody = await request.json();
return HttpResponse.json({ id: 123, ...reqBody }, { status: 201 });
},
);
Please use mswpida v1 for MSW v1.
MIT