1

On multiple occasions, we've deployed frontend code to production only to find out the backend (REST or GraphQL) hasn't shipped their side yet. Worse yet, we unexpectedly find out a param name changed which may throw an error. Another example: the backend removes an API thinking that clients no longer use the removed API and the frontend crashes. If any layer of communication between frontend and backend breaks down, then we may end up with catastrophic errors.

I think the "best solution" is to use a tool like Cypress or Codecept to create a suite of integration tests which checks every API call the frontend may use. Sadly, that's a heavyweight solution that requires significant upfront investment in developer time.

Anyway, I'm looking for simple solution to this problem. Maybe something that checks affected APIs when the frontend opens a PR and/or something that checks the frontend repo when the backend deploys to production.

Any ideas or experience solving this problem?

2
  • 2
    The best solution is that people start talking to each other to discuss issues around the API like deployment, renames, deprecation, etc. May 24, 2020 at 7:52
  • @BartvanIngenSchenau Absolutely. Unfortunately, folks drop the ball sometimes and not everything is documented or discussed with the other side of the house.
    – Brandon
    May 26, 2020 at 11:20

2 Answers 2

4

On multiple occasions, we've deployed frontend code to production only to find out the backend (REST or GraphQL) hasn't shipped their side yet.

If a system relies on synchronized deployments for frontend and backend, you either need to synchronize them more strictly (which is an organizational problem), or develop the system in a way it is more tolerant against time shifts in deployment (see below).

Worse yet, we expectedly find out a param name changed which may throw an error.

There is nothing wrong when the frontend expects a certain version of the backend, that this will produce an error. However, the error itself should be of the form "wrong backend version, minimum expected version is 32.0, currently installed version 31.0". So someone who gets informed about this error gets a clear information what has to be fixed, not just an unclear message that the system does not work.

To achieve this, your backend needs to provide a stable mechanism to let the frontend query it's version number. And obviously your backend needs to have a proper version number, that should be self-evident.

Another example: the backend removes an API thinking that clients no longer use the removed API and the frontend crashes.

This is where it comes to the point I mentioned above: "more tolerance against time shifts in deployment". You achieve this by

  • avoiding non-backward API changes whenever feasible (providing backwards-compatible API calls, even when there are newer, "better" calls available for now)

  • have a strict procedure for deprecating older APIs when you think it is time for this: this needs to include a way to communicate intended API changes to the frontend team in time, and a way to technically check that the old API isn't really used any more by the deployed frontends

So the usual cycle to change a certain part of an API in a non-backwards compatible manner should be

  • first develop the new API version, but let the old API still in place

  • deploy a new version of the backend - nothing breaks

  • tell the frontend team about the intended API deprecation and let them change the frontend accordingly

  • deploy new versions of the frontend (and make sure the frontend was deployed to production completely and replaces the former version on all clients)

  • make sure the frontend really does not call the old API any more

  • then remove the old API from the backend and deploy a new version of the backend.

3

There probably isn't a simple general solution. You need stable API versions and some way of specifying which API versions are being provided by each back-end code version, and which API versions are required by front-end code versions.

API versioning

SemVer provides a framework in which these things can be expressed and checked. This should be enough to be confident that a given front-end version can be used with the current back-end or requires deployment of a new back-end version.

API specification/documentation

One way to systematically document APIs is OpenAPI (formerly known as Swagger.) There are tools to support the generation of OpenAPI documents (in the form of JSON files) from annotated code for many languages, and also tools to generate API stubs from OpenAPI documents. It should also be possible to check whether one API is a backward compatible and thus could get just an incremented minor version number.

To get things started, you may want to document the currently implemented APIs using OpenAPI and give them a version number sich as 1.0.0. When new features are implemented, see whether they can be done in backward compatible ways and just require new minor versions, or whether a new major version is needed. If you introduce new major versions, your backend should support the previous version, too, as long as front-ends using it are in the wild.

Automatic check that can be included in your CI pipeline are the last thing to do, after your API specification and versioning process is stable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.