Home > Enterprise >  @mswjs/data question: why does RTK-Query sandbox example need separately handcoded POST and PUT mock
@mswjs/data question: why does RTK-Query sandbox example need separately handcoded POST and PUT mock

Time:12-15

This is a question about the default behaviour of @mswjs/data.toHandlers function using this example with @mswjs/data to create mocks for RTK-Query calls.

https://codesandbox.io/s/github/reduxjs/redux-toolkit/tree/master/examples/query/react/mutations?from-embed

the file src/mocks/db.ts creates a mock database using @mswjs/data and defines default http mock responses using ...db.post.toHandlers('rest') but fails to work if I remove the additional PUT and POST mocks.

My understanding is that @mswjs/data toHandlers() function provides PUT and POST mock API calls for a defined database (in this case Posts) by default according to the github documentation so I am seeking advice to understand better why toHandlers does not work for PUT and POST in this example. i.e. if i remove PUT and POST mock API calls they fail.

What do the manual PUT and POST API mocks do that the default toHandlers dont?

CodePudding user response:

You are correct to state that .toHandlers() generates both POST /posts and PUT /posts/:id request handlers. The RTK-Query example adds those handlers explicitly for the following reasons:

  1. To emulate flaky error behavior by returning an error response based on the Math.random() value in the handler.
  2. To set the id primary key to nanoid().

Adding a post fails if you remove the explicit POST /posts handler because the model definition for post does not define the initial value for the id primary key. You cannot create an entity without providing a primary key to it, which the example does not:

// PostManager.tsx
// The "post" state only contains the name of the new post.
const [post, setPost] = useState<Pick<Post, "name">>(initialValue);

// Only the "post" state is passed to the code that dispatches the
// "POST /posts" request handled by MSW.
await addPost(post).unwrap();

If we omit the random error behavior, I think the example should've used nanoid as the initial value of the id property in the model description:

import { nanoid } from "@reduxjs/toolkit";

const db = factory({
  post: {
-   id: primaryKey(String),
    id: primaryKey(nanoid),
    name: String
  }
});

This way you would be able to create new posts by supplying the name only. The value of the id primary key would be generated using the value getter—the nanoid function.

The post edit operation functions correctly even if you remove the explicit PUT /posts/:id request handler because, unlike the POST handler, the PUT one is only there to implement a flaky error behavior (the edited post id is provided in the path parameters: req.params.id).

  • Related