Scale your react project: use mocks to decouple backend from frontend development
August 16, 2022
Ready to start?
Introduction
In many full stack application development teams, it is quite common to have frontend engineers who are frustrated with the developer experience regarding the webapps they are building. This usually happens because the frontend development process in their company is heavily coupled with a backend server and a database behind it. The web app cannot run locally without a dedicated development server.
Many front-end engineers are having a hard time dealing with development server downtime, lack of API, or just need to constantly switch between backend environments. All with the sole purpose of building a feature that lives entirely in their local browser. This can really hurt development velocity, especially in large enterprise organizations which have a lot of potentially breakable moving parts.
There’s a solution here, which can keep your frontend development 100% decoupled from any backend code. This is what this post is about.
What does decoupling the backend from the frontend have to do with developer experience?
Let’s take a look at a traditional feature development process in a full-stack application:
As you can see, throughout the development of an average feature the frontend team is blocked the most. The frontend team is forced to wait for the backend team to finish up their work because without an API, building the frontend part of the feature will be difficult to complete. In most cases the frontend team just waits for the backend team to fully complete their part of the feature.
Doesn’t look too bad? Take a look at a more down to earth early-startup diagram:
About 50% of the development time is spent in “blocked” state. The severity changes between features, teams and companies but the point remains the same. This kind of developer (non-)velocity creates exhaustion, laziness, and extreme lack of productivity. I’ve met FE developers that couldn’t make any progress at all for days because of “external reasons”. This can also create a ping-pong culture that can ultimately end up with people feeling a growing frustration and potentially leaving the company.
The solution: mocks
A proper UI-mocks infrastructure can easily solve this problem.
If the frontend team creates mocks in the product planning phase, most of those red squares in the frontend team timeline axis can turn to yellow or green (which represent progress and feature complete respectively) because the FE project can live in its own “mock UI bubble”, detached and de-coupled from any external sources.
Here is a developer velocity comparison diagram between a traditional frontend project and a frontend project that relies on mocks for the development process:
No surprises there, obviously. The development of webapps with mocks allows the developer to take full control of all variables. It allows for a development process that is decoupled from any unexpected external source. It also allows starting the development of the feature immediately once the design and specifications in the “product + design phase” are completed.
In my opinion, the most important aspect of developer experience is independence. If I constantly must communicate with other teams in my organization about downtimes, API documents and permissions, it reduces my productivity and my ability to learn new things. Mocks help with all of these things, because all I have to do is to agree on the way a feature should be done, and from that point every team can progress on its own.
{{cta_5}}
Tools and Tips
There are some tools and libraries out there that can help architect mocks pretty easily.
Mock Service Worker Library (MSW)
The most notable open-source package in this space is the Mock Service Worker Library (MSW). Essentially the library intercepts the browser’s network requests, allowing the developer to “force” a custom response for a network request, suited for his needs.
This library registers a Service Worker that listens to the application's outgoing requests via the fetch event, directs those requests to the client-side library, and sends a mocked response, if any, to the worker to respond with.
Here's a high-level overview of the Mock Service Worker request flow:
The main advantage is that the mocks live as part of the webapp project and not as a separate entity. It could be useful if you’d want to enforce typing, use the mocks for your FE testing infrastructure or easily create data for a customer demo.
JSON Server
Another great mention is the JSON Server library. The library enables the developer to easily create mocks as part of a separated server. It’s a more classic approach to creating mocks but works just as well.
Falso
It is worth mentioning that if you’d want to create data that looks real, you might want tools that can help you generate random data. A great library for that purpose is Falso. The library offers a variety of data utilities to create random data and it has great documentation.
Make sure the mocks align with the real API
It would be a pity if you’ll work hard to develop a particular feature, only to find out that the mocks you’ve created don’t align with the real API of the feature. The mocks don't have to be 100% accurate, because that would slow down development. But they should provide a pretty good initial representation of how the API will actually behave
Don’t over-engineer mocks
If you find yourself complicating things, reconsider your actions. The mocks are not a feature you are required to build. It is merely a tool that helps you build features faster. Adopt the “good enough for this feature” approach, and scale it up as your team grows.
Make sure other FE engineers are aware of the ability to build mocks on their own
Using mocks in a FE project is a relatively new approach. Most FE engineers out there are not familiar with the concept. Make sure everyone knows about the ability to mock things and teach them how to create mocks on their own.
Don’t mock mutation routes
What I mean by that is that your backend server probably has routes that ultimately update the records in the database.
I highly recommend to make it simple and mock only the status codes and not manage a state just to update/create/delete records or data in the server.
This is because generally speaking, you need the mocks to display data in the webapp. Handling updates, creation or deletions would require you to have some kind of client-side state just for this purpose, which complicates the concept a lot. I rarely mock anything other than GET requests. Our purpose is not to create a second backend server in our project, but to create the minimal shallow version of our API to the point where it will be “good enough”.
{{ebook}}
Conclusion
Using mocks as part of your development process can have a tremendous impact on your developer experience and velocity. It is also a relief to the other teams in the organization because they do not have to rush with their part of the features just in order to not leave the frontend engineers in a blocked state or creating numerous dev environments.
Check out Port's pre-populated demo and see what it's all about.
No email required
Contact sales for a technical product walkthrough
Open a free Port account. No credit card required
Watch Port live coding videos - setting up an internal developer portal & platform
Check out Port's pre-populated demo and see what it's all about.
(no email required)
Contact sales for a technical product walkthrough
Open a free Port account. No credit card required
Watch Port live coding videos - setting up an internal developer portal & platform
Book a demo right now to check out Port's developer portal yourself
Apply to join the Beta for Port's new Backstage plugin
It's a Trap - Jenkins as Self service UI
Further reading:
Example JSON block
Order Domain
Cart System
Products System
Cart Resource
Cart API
Core Kafka Library
Core Payment Library
Cart Service JSON
Products Service JSON
Component Blueprint
Resource Blueprint
API Blueprint
Domain Blueprint
System Blueprint
Microservices SDLC
Scaffold a new microservice
Deploy (canary or blue-green)
Feature flagging
Revert
Lock deployments
Add Secret
Force merge pull request (skip tests on crises)
Add environment variable to service
Add IaC to the service
Upgrade package version
Development environments
Spin up a developer environment for 5 days
ETL mock data to environment
Invite developer to the environment
Extend TTL by 3 days
Cloud resources
Provision a cloud resource
Modify a cloud resource
Get permissions to access cloud resource
SRE actions
Update pod count
Update auto-scaling group
Execute incident response runbook automation
Data Engineering
Add / Remove / Update Column to table
Run Airflow DAG
Duplicate table
Backoffice
Change customer configuration
Update customer software version
Upgrade - Downgrade plan tier
Create - Delete customer
Machine learning actions
Train model
Pre-process dataset
Deploy
A/B testing traffic route
Revert
Spin up remote Jupyter notebook
Engineering tools
Observability
Tasks management
CI/CD
On-Call management
Troubleshooting tools
DevSecOps
Runbooks
Infrastructure
Cloud Resources
K8S
Containers & Serverless
IaC
Databases
Environments
Regions
Software and more
Microservices
Docker Images
Docs
APIs
3rd parties
Runbooks
Cron jobs