learn react ui logoLearnReactUI
Address Options Mocking With MSW

How to Mock Server APIs (No Server Costs) Example

This project implements Address Options Mocking using MSW (Mock Service Worker) to simulate API responses for address selection. It enables seamless testing and development by providing mocked address suggestions, handling user inputs, and simulating dynamic API behavior.

[Demo1] [Demo2]

1. Use Case

First, let’s speak about the use case. I’ll demonstrate how we can implement address dropdown choices without using a real server by establishing a fake server on the client side (in the browser).

Address Options

First and foremost, I have previously published a blog on the issue. Essentially, the browser performs rendering activities in a single process and event loop. We utilize Web Worker or its specialized version Service Worker for performance (for example, background computation on the map) or other mimicking actions that we want to do concurrently. MSW is a mock creation tool built with this Service Worker.

Address Form Example

In our first example Address Form [Demo], our goal is to create an environment where the Dropdown components and its content are fixed.

Address Form Sample

First, we write our components. We create the Province, District, and Neighborhood Dropdowns.

const renderDemo = () => {
  const districtArr = districts.filter((el) => el.value.includes(selectedCity));
  const neighborhoodArr = neighborhoods.filter((el) =>
    el.value.includes(selectedDistrict)
  );
  return (
    <div style={{ display: "flex", gap: "3px", alignItems: "center" }}>
      <Typography.Text strong>Address Form</Typography.Text>
      <Select
        style={{ width: 150 }}
        options={cities}
        onChange={onCityChange}
        optionLabel="name"
        placeholder="Il Sec"
      />
      <Select
        style={{ width: 150 }}
        options={districtArr}
        onChange={onDistrictChange}
        optionLabel="name"
        placeholder="Ilce Sec"
      />
      <Select
        style={{ width: 150 }}
        options={neighborhoodArr}
        onChange={onNeighborhoodChange}
        optionLabel="name"
        placeholder="Mahalle Sec"
      />
      <Button type="primary" onClick={handleApply}>
        Submit
      </Button>
    </div>
  );
};

The next thing is to create the content within it.

export const neighborhoods = [
  { label: "Beşiktaş_Mahalle1", value: "IST_BSK_MH1" },
  { label: "Beşiktaş_Mahalle2", value: "IST_BSK_MH2" },
  { label: "Kadıköy_Mahalle1", value: "IST_KAD_MH1" },
  { label: "Kadıköy_Mahalle2", value: "IST_KAD_MH2" },
  { label: "Beyoğlu_Mahalle1", value: "IST_BEY_MH1" },
  { label: "Beyoğlu_Mahalle2", value: "IST_BEY_MH2" },
  { label: "Çankaya_Mahalle1", value: "ANK_CANK_MH1" },
  { label: "Çankaya_Mahalle2", value: "ANK_CANK_MH2" },
  { label: "Keçiören_Mahalle1", value: "ANK_KEC_MH1" },
  { label: "Keçiören_Mahalle2", value: "ANK_KEC_MH2" },
  { label: "Yenimahalle_Mahalle1", value: "ANK_YNM_MH1" },
  { label: "Yenimahalle_Mahalle2", value: "ANK_YNM_MH2" },
];

export const districts = [
  { label: "Beşiktaş", value: "IST_BSK" },
  { label: "Kadıköy", value: "IST_KAD" },
  { label: "Beyoğlu", value: "IST_BEY" },
  { label: "Çankaya", value: "ANK_CANK" },
  { label: "Keçiören", value: "ANK_KEC" },
  { label: "Yenimahalle", value: "ANK_YNM" },
];

export const cities = [
  { label: "Istanbul", value: "IST" },
  { label: "Ankara", value: "ANK" },
];

We have now produced static mockdata. When we pass this data straight to the components as props, we generate a simple mock.

AdressForm Concept

Address Fetch Example

In the second example, we’d want to complicate matters even further by using a real server and a retrieve request. In other words, a request will be issued from the network layer, returned from the server, and the dropdowns will be updated accordingly.

AdressFetch Concept

What are the benefits of having an MSW?

  • We can write more realistic exams.
  • The cost is quite inexpensive.
  • You do not need to update your live code (ReactQuery, Fetch/Axios, etc.), and you can continue to use your structures as before.

Let us now look at the Address Fetch [Demo] example. In this example, in the background, we turn the static data into an HTTP Callback Handler.

import { HttpResponse, http } from "msw";
export const restApiUri = "https://api.onurdayibasi.dev";

export const cityHandlers = [
  http.get(`${restApiUri}/address/cities`, async () => {
    return HttpResponse.json(cities);
  }),

  http.get(`${restApiUri}/address/districts`, async () => {
    return HttpResponse.json(districts);
  }),

  http.get(`${restApiUri}/address/neighborhoods`, async () => {
    return HttpResponse.json(neighborhoods);
  }),
];

After this handle operation, we assign it to MSW worker.

import { setupWorker } from "msw/browser";
import { cityHandlers } from "@garden/mocks/cityHandlers";

export const mockServerWorker = setupWorker(...cityHandlers);

Now we have a structure that can respond to the requests made through the server and respond to these requests.