logoGERASOFT
Blog

From Idea to App - How to transition to a New API

Reading time: 3-8 minsTechnicality: 5/5Last updated: Mar 23, 2025
From Idea to App - How to transition to a New API

In the last post we successfully implemented authentication and wired together our web app with the API. However, we are still using the temporary local mock API that imitates the task management operations. Now that the real API connected with our database is live on the server, it’s time to replace our mock API with the real one.

Original motivation

Just a quick detour to answer the question: “What was the point in spending time implementing a mock API when it was known in advance that it will be replaced?”.

Building up our backend wasn’t an easy and quick task which you may have noticed if you followed our series.

If we would have implemented backend first, we still couldn’t showcase the app to our users, gather feedback, and iterate on the product. Even though our database, backend, and frontend work well together locally, we still need to set up our infrastructure to be able to go live.

In comparison, doing duplicate work by implementing the mock API, we bought ourselves several weeks head start to gather valuable feedback, and build our presence.

Upcoming

We will replace our mock API with the GraphQL API, so all task operations (creation, reading, updating, deleting) will be done by the live server, and performed on the database. This includes:

  • Replace mockTaskApi operations with the hooks provided by the GraphQL API.
  • Remove mockTaskApi , and MockTaskType .
  • Implement loading states in the screens (it wasn't needed when using the mock API as it didn't require network requests).

Resources

ClickUp ticket

GitHub changes

Remove mock API

To begin, we removed the entire mockTaskApi store from the codebase. This included:

  • Deleting the Zustand-based store logic.
  • Removing the MockTaskType type.
  • Eliminating test utilities such as usePopulateTasks.

With the mock layer gone, we transitioned all task-related logic to use the real GraphQL API.

Replacing Each Operation

Here is a complete list of one-to-one replacements made across the app:

  • Fetching all tasks

    Replaced getTasks() from the mock store with the useGetTasksQuery() Apollo hook.

  • Fetching a single task by ID

    Replaced getTaskById(id) with useGetTaskQuery({ variables: { _id: id } }).

  • Creating a task

    Replaced createTask(name) with the useCreateTaskMutation() hook, passing the task name as mutation variables.

  • Updating a task

    Replaced updateTask(id, updatedFields) with useUpdateTaskMutation(), supplying all fields through the variables parameter.

  • Deleting a task

    Replaced deleteTask(id) with the useDeleteTaskMutation() hook and appropriate variables.

Each mutation now optionally refetches GetTasks to ensure that the UI reflects the latest data after operations.

Implementing Loading States

Previously, the mock API responded instantly, so loading indicators weren’t necessary. With real network requests in play, we implemented loading states across the app to ensure a smooth user experience:

  • A spinner appears while tasks are being fetched on the main screen.
  • Forms and buttons are disabled during creation, updates, or deletion to prevent accidental resubmissions.
  • The EditTask modal shows a loading indicator before task data is available.

Test and Storybook Migration

Alongside the main application, all tests and Storybook stories have been fully migrated to use the new GraphQL structure. This involved replacing mock store dependencies with Apollo mocks and ensuring all components behave consistently under real-world data flow, including loading and mutation states. The test suite now operates against realistic scenarios, and Storybook reflects the same GraphQL-driven architecture used in production.

What We Gained

This transition marks a major milestone:

  • A real backend connection — All task operations now persist to the database.
  • Consistency — The frontend uses the same API for authentication and task management.
  • Improved UX — Users get responsive feedback via loading indicators and stateful UI.
  • Codebase clarity — We’ve removed all temporary scaffolding, leaving only production-ready logic.

Next steps

Our MVP app is in a pretty good shape now. We have a working frontend and backend, but it only works locally on a development server.

To bring our app to life, we will have to set up our infrastructure to have the environment ready to deploy our app. This includes:

  • Set up a cloud database via MongoDB
  • Set up AWS account for infrastructure
  • Register domain for hosting the web app
  • Set up storage and distribution for the web app
  • Set up server infrastructure:
    • Load balancing
    • Scaling
    • Deployment

Here's how our timeline look like now:

12345678910
Set up infrastructure
10 d