πŸ†•Beta functionality

Supporting beta features is not that hard. Let's do it!

We have built in a "beta functionality" concept that is propagated from feature toggles into our services. This is a catch-all for new features that we want to test, and which may not yet be ready for wider release. This means that our services need to have distinct checks for this, though.

As you can see in the next section on feature toggles, we can also use user groups to segment features, as well as classic, individual toggles that can be used on a per-user basis.

What gives? Aren't these beta features just like any other toggles? Yes. In this project, we define ”beta features” as a feature-level, wide bucket across user groups, while user grouping is a dynamically wide bucket (basically just audience segmentation). This way, we can define granularly both user groups and on beta usage.

🎯 Example: See for example src/FakeUser/usecases/createFakeUser.ts that uses the provided toggles when calling the User entity which dynamically creates different types of users from this toggle.

src/FakeUser/usecases/createFakeUser.ts
import { UserData, UserDataExtended, User } from "../entities/User";

import { getData } from "./interactors/getData";
import { getImage } from "./interactors/getImage";

/**
 * @description This is where we orchestrate the work needed to fulfill our use case "create a fake user".
 */
export async function createFakeUser(
  toggles: Record<string, unknown>
): Promise<UserData | UserDataExtended> {
  // Use of catAPI is same in all cases
  const user = new User(toggles.enableBetaFeatures as boolean | false);
  const imageResponse = await getImage("catAPI");
  user.applyUserImageFromCatApi(imageResponse); // <-- Rich entity object has dedicated functionality for differing data sources

  // Use code branching for new development feature
  if (toggles.enableNewUserApi) {
    const dataResponse = await getData("RandomUser");
    user.applyUserDataFromRandomUser(dataResponse); // <-- Rich entity object has dedicated functionality for differing data sources
  }
  // Else return regular response
  else {
    const dataResponse = await getData("JSONPlaceholder");
    user.applyUserDataFromJsonPlaceholder(dataResponse); // <-- Rich entity object has dedicated functionality for differing data sources
  }

  return user.viewUserData();
}

Last updated