We recently built a side-project with Emmanuel Lodovice and Aldrin Navarro named Endpoints, a Web application that allows you to generate a mock endpoint where you can send HTTP requests to, view a log of these requests, and set a customized HTTP response. You can check out the live application at endpoints.uncaughtexception.wtf or the source code at GitHub.
This post gives an overview of how the application’s frontend was built and the different technologies that we used. If you’re interested in knowing how the backend was built, you can read Emmanuel Lodovice’s article about it:
Building the backend for Endpoints project
We recently built a side-project with Arnelle Balane and Aldrin Navarro named Endpoints, a web application that allows…
The Endpoints app has three pages, and they are all structured as a Single Page Application (SPA). To achieve this, we used Vue’ official client-side router,
vue-router. It takes care of identifying which Vue component should be render based on the URL, and rendering that component without reloading the page.
Vue-router also supports lazy-loading the components, which means that the components are only downloaded by the browser only when they are the ones that are going to be rendered. This is helpful for reducing our bundle size, allowing the browser to download them faster and rendering our app faster. We used this feature for the Vue components representing each page, which makes Vue download the code for that component only when its URL is visited.
vuex to manage the states of our application. It allowed us to keep all our state (available endpoints, request logs, response data, etc.) in a single central location called a “store”. These states are then easily accessed by different components instead of having to be passed as props from parent to child. Vuex also gives us mechanisms (mutations and actions) to easily manipulate the states.
Using a vuex store as our single source of truth for our application state makes it easier to synchronize data across different components, since we only need to read or modify it in one location. Additionally, all our code that interact with our backend are also placed inside the vuex store.
Several Web platform APIs were used to implement the different functionalities of the project.
We used the Fetch API to programmatically send HTTP requests to our backend server. We used it to either send data to the backend (e.g. a request to create a new endpoint) or retrieve data from it (e.g. obtaining live status of an endpoint).
One feature of the Endpoints app is that it shows a real-time log of HTTP requests that your endpoint receives. In order to do this, we established a WebSocket connection between the browser and our backend server. This allows our backend server to send request logs data to the browser as they arrive.
Webpack uses “loaders” to process modules, and there are different loaders for processing specific types of modules. In the case of the Endpoints app, here are the ones that we used:
vue-loaderfor processing Vue’s Single File Components.
css-loaderfor processing stylesheets.
url-loaderwhich inlines small assets (e.g. images, etc.) within the module that uses them.
I mentioned earlier that we only load Vue components only when its URL. In order to do this, we needed split the code for these components out of the main bundle and into their own smaller bundles, which are then going to be the ones that are lazy-loaded at the appropriate time. Using vue-loader automatically does this for us.
We performed additional steps in order to optimize our assets for production. We minified the bundles that we serve in production using the
UglifyJSPlugin for Webpack. But we only do this when
NODE_ENV=production is set in order to not slow down development builds.
So that’s the quick overview of how we built the frontend part of the Endpoints project. We tried to keep the setup and configurations as minimal as possible, and I think we did a decent job at doing that. You are welcome to dig deeper into the code in the GitHub repository.
Thanks for reading!