You can build the frontend without the backend.
Tags: webdev, javascript, design, codenewbie
Published: 2021-07-25 02:31:33

# Building independently

Often I'd work with teams that either build the frontend or backend individually. One challenge I typically see in this model is the interdependency between the teams.

For example, the the frontend devs would be stuck waiting on an endpoint from the backend devs to finish a feature. However, it doesn't have to be this way. Some thoughtful design and documentation can go a long way to improve efficiency.

# Case Study

So you are the frontend team building an app that lets you login and retrieve the friends of a user given their userid.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2bs448df3mcfk88lwvfk.png)

The problem is you don't know anything about the backend, the url, auth scheme etc other than it provides a JSON REST API. 

# Handling the unknown

The idea is to structure your code such that changes in one component would have minimal to no changes in another. You can modularize your code by restricting all details related to the backend a file composed of API Functions/services. These functions are then are called by the rest of the codebase.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l5h561h3krhh5nroc23a.png) 
 
This structure appeals to the [separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns) design principle. This way, any changes in the backend will not affect any of your UI logic.

# Example

Instead of tying the network call for logging in inside of the login button event handler, the form data is passed to an API function which then sends the request.

```javascript
//inside main.js

import { login } from './api.js';

//get all required input and send to the service
async function loginAction(event){
  const form = event.target;
  const { username, password } = form.elements;
  const result = await login(username, password);//call API function
  alert(result.message);
}
```
Then in the API functions file, the login function takes the required parameters, makes the network call and returns the response.

```javascript
//inside api.js
//sendRequest() is a custom function that calls fetch()

const SERVER = "idk";

async function login(username, password){
  // return sendRequest(`${SERVER}/login`, 'POST', {username, password })
  return { message:'success', token:'3poisjd90fusdfasdf'};
}

export { login }
```

Remember we don't even know the server's endpoint so what we do here is develop a [stub](https://en.wikipedia.org/wiki/Test_stub) which would return a dummy result that we'd otherwise expect from the real endpoint. 

This is really important because now the UI logic that calls this function can be fully implemented.

# API Specification

When the endpoint is ready we can easily update this function to use it instead with zero change to the UI code! At this point you will also make it clear exactly what should send and what should be returned by the backend by looking at the input and output of the function. 

This is great if you are working with a separate backend team cause from there you can create an API Specification document for collaboration.

| Request Name       | URL                     | Method | Request Body                                             | Response Body                                                  | Response Status |
|--------------------|-------------------------|--------|----------------------------------------------------------|----------------------------------------------------------------|-----------------|
| Successful Login   | /login                  | POST   | {   'username':'<username>',   'password':'<password>' } | {  'message':'successful',  'token': '<token>' }               | 200             |

This can be put in a google doc acting as the main source of truth for both teams and allow them to iterate without needing to even look at the other team's code.

# Wrapping Up
This is just a case study on how documentation and design can actually make work more manageable. I have a full example of this app running on replit where you can see how the Get Friends feature is also simulated.

{% replit @Snickdx/services-architecture %}