...

/

Cope with Changing Business Requirements

Cope with Changing Business Requirements

Learn how to structure our code for changing business requirements.

Overview

Writing a greenfield application in FP is usually the easy part. Once the application is running, it will have to evolve alongside changing business requirements. How will our code cope with change? Let’s try making a few changes and see what happens while taking care not to introduce too many new concepts.

Adding a basic check in the application

First, let’s look at a relatively easy change, an additional check. Because we haven’t run any checks on the country, we’ll add a check through which we’ll refuse users from Germany.

The function type will be similar to that of the other checks. Let’s add one in the domain.ts file.

Press + to interact
export type ValidateNotGerman = FieldsNotEmpty;

The code for checking that the country isn’t Germany can be as follows in our functions.ts file:

Press + to interact
const validateNotGerman: ValidateNotGerman = (e) => {
return e.country !== 'Germany' ?
E.right(e) : E.left("We don't like your kind around here");
};

The validation check doesn’t look too difficult. We just placed the check behind the existing ones to add it to our application.

Press + to interact
function flow(u: UserRegistrationDto) {
return pipe(
fieldsNotEmpty(u),
E.chain(validateAge),
E.chain(validateGender),
E.chain(validateNotGerman), // this is the only change
E.map(userResponse),
E.getOrElse(badRequest),
);
}

The application gives back the same results as before, except when we pass in Germany as a country.

{
    status: 400,
    message: "Pass a country other than Germany."
}

That was easy. After our other checks, we created a new function and added it to our pipe function. Perhaps most importantly, from the viewpoint of extending an existing application, we didn’t touch any existing functions (excluding flow, which still has the same signature). We didn’t change any of the checks that were already present. This is ...