Programmatic mock API from the client using hapi(no server?needed)
Disclaimer: the only AI used here was to correct grammatical mistakes??
One valuable tool I have learned in my workplace has been using programmatic mock API to test existing and future features from the client side. Why programmatic? because once implemented, it would be easy to escalate it and add more services as needed.
These are the potential practical scenarios to implement this tool:
Everything you need to know beforehand
Since developers can implement the concepts in different code formats, standards, and frameworks, I will clarify the general steps and reduce the number of code blocks so that you can adapt these steps to your criteria. Thus, it is required that you already know:
We should get to the point.
For the context of this endeavor, let's understand Hapi as an open-source Node.js framework that provides features and toolkits for creating APIs, HTTP-proxy applications, and websites, among other great stuff. In general terms, it will help you create a server. Please follow the steps to install it as explained in their?docs?and?wait to create the server.?
With that said:
1. Directory structure:?let's create a unique directory for this effort from the root project. Feel free to call it as you want, but?mock-api?could be a good choice. In this directory, we can have two sub-directories, one to handle?data?(the mocked JSON database) and another to take?methods(to add, update, or eliminate data as requested). We can also include an index module to create our mocked server and provide the endpoint routes.
mock-api/
├── data/
├── responses/
└── index.ts
2. Mock data:?We will want to create a unique module, one per service, in the data directory. Each module will contain the JSON data structures needed.
?Align your goals:?Just so you know, before creating the data structure, please make sure you have clear the nature and behavior of your service and interaction with the UI. That will help you and your team define the internal data type you need inside those JSON objects.
?Feel free to support yourself with AI to save time or create extensive data.
Just in case, we still don't need Hapi at this point.
mock-api/
└── data/
├── service-1.ts
├── service-2.ts
└── service-3.ts
3. Mock HTTP responses:?now the main character(Hapi) appears. On each responses module, let's invoke two important tools from hapi?Request?and?ResponseToolkit
mock-api/
└── responses/
├── service-1.ts
├── service-2.ts
└── service-3.ts
Each module should look like this:
领英推荐
import { Request, ResponseToolkit } from '@hapi/hapi';
import { getData } from '../data/service-1.ts';
export function getServiceData (request: Request h: ResponseToolkit) {
const data = getData(request.payload);
if(data) {
return h
.response({
message: data,
})
.code(200);
}
return h.response({ message: "Something went wrong" }).code(400);
};
And above is the magic of hapi. No matter what framework you use, it will provide you with the structure to generate a correct HTTP response.
The response toolkit is a collection of properties and utilities passed to every?lifecycle method. It is somewhat hard to define as it provides both utilities for manipulating responses as well as other information. Since the toolkit is passed as a function argument, developers can name it whatever they want. For the purpose of this document the h notation is used. It is named in the spirit of the RethinkDB r method, with h for?hapi.
At this point, you can create as many HTTP responses as needed. In the above example, we made a simple GET response with a 200 status code. Still, receiving a 400 status code is possible if we receive the correct input. We can also create a POST, DELETE, PATCH, PUT, and other functions such as executing a process. For some of them, we would need to send the data to be altered in the body in the same request parameter.
4. Mock endpoints:?here is where index.ts comes into place. We will create the mocked server and each service's corresponding routes/endpoints.
mock-api/
└── index.ts
import Hapi from '@hapi/hapi';
import { getServiceData } from './responses/service-1';
import { postService2Data } from './responses/service-2';
async function init() {
const server = Hapi.server({ port: 4000 });
server.route({
method: 'GET',
path: '/api/fndsGroups',
handler: getServiceData,
});
server.route({
method: 'POST',
path: '/api/fndsGroups',
handler: pospostService2Data,
});
server.route({
method: 'GET',
path: '/{any*}',
handler: (request, h) => h.response({ message: `Route not matched: ${request.url}` }).code(404),
});
await server.start();
console.log('? Mock API ready on port 4000');
}
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
Let's break it down:
5. Components API calls:?In this part of the process, we want to connect our UI components to interact with these endpoints. I won't get into the details since there is no single way to do this.
6. Running mock-data build locally:?we want this build to be separated from our production build or other environments.
First, we need to install nodemon, a utility that helps us restart our server automatically whenever we change our code with the?-watch?flag. Also, it will help us execute the local mocked server with the -exec flag. Here is the?installation guide.
After that, we can include the following in our package.json scripts:
"start:api-mock": "nodemon — watch 'mock-api/**' — ext' ts,json' — exec 'ts-node mock-api/index.ts'"
7. Testing:?After connecting the mock-api with our components, we are ready to test the behavior of our UI. Also, an extensive set of unit tests is part of the programmatic effort to ensure quality.
?AI could be a great help here.
From here, we can make adjustments and, more importantly, decide whether we should continue nurturing this effort.
<a href="https://www.freepik.com/free-vector/software-code-testing-concept-illustration_21532463.htm#query=testing&position=0&from_view=search&track=sph&uuid=379bad1d-29b9-4d77-86fd-bde7ba151e10">Image by storyset</a> on Freepik