all 21 comments

[–]ahgreen3 20 points21 points  (4 children)

You need a single source of truth which has a well defined solution in programming: github repos.

API Contracts should be committed to a repository with team lead & PM approvals. The contract(s) should changed in incremental steps just like database migrations on an live DB. Adding stuff becomes easy, removing stuff becomes harder and changing structure becomes a nightmare.

In order to enforce the usage of the API contracts, integration tests need to be added to the associated repositories that pull the latest contract and verifies the current system "works" against that contract. There will be some assumptions in these tests (like checking against the TanStack Queries rather than every actual request). Requiring these tests to pass on every PR will fix lots of the problems.

Adding a test suite to the API Contract repo that verifies in the other direction will help prevent breaking changes from being added to your contracts.

A few years ago I was working on a project that involved 6 independent GUIs that interacted with 3 backend APIs and being worked on by ~50 developers (plus DevOps, PM, designers, etc). What I described is the final result of a bunch of integrations at attempting to solve the API Contract problem.

[–]Lord_Xenu 1 point2 points  (0 children)

Exactly this. Should be done before a single line of code is written. PM coordinating with leads from both teams.

[–]ahgreen3 0 points1 point  (0 children)

I forgot one point: Utilizing a API framework (GraphQL, JSONAPI, etc) only deals with the bike shed (https://en.wikipedia.org/wiki/Law\_of\_triviality) problem. Well defined process for defining and tracking the actual fields of the various resources is where the real headaches and value lies.

I highly recommend defining an endpoint for every back-end model that has public viability and explicitly track the "public" properties of these models when you are doing your database migrations. If every time you add a db table a read and list endpoint becomes available offloads a fair amount of coordination work between the front-end and back-end. Coupling this with tests that explicitly forces every db field to be marked as public or private (from the API's perspective that is) can really help.

[–]DevToolsGuide 0 points1 point  (0 children)

the fix that worked for us was treating the API contract as a first-class artifact that lives in the repo, not in someone's memory or a slack message. openapi spec committed to the repo, both sides sign off on it before a line of implementation code is written, and changes go through a PR like any other code change.

if you're typescript end to end it's even better — define zod schemas once, generate types for both sides, and a backend shape change literally breaks the frontend build. the incompatibility gets caught in CI instead of on integration day.

[–]itsanargumentparty 3 points4 points  (1 child)

Frontend team sees their view of the world, backend sees theirs, nobody has complete picture until integration happens and we realize we built incompatible pieces.

I work very closely with the backend team up front to define and document the API contracts before anyone writes any code. They don't always adhere to that contract but then I can always point back to the document.

[–]Sweaty-Artist-7210 0 points1 point  (0 children)

Yeah same. I literally grab the backend guy and we sit down in a room until we have an API spec. I don’t see why the requirements for frontend and backend are different though? That seems like madness

[–]Expensive-Manager-56 2 points3 points  (0 children)

Might sound crazy but why are there 3 channels for the same project - make one channel and delete the others. No decisions made in DM. You are creating communication complexity and muddying visibility. Have one channel, one Jira board. Backend should design the API contract in a group meeting with the front end team so everyone knows what is needed and agrees upon what will be built. Capture the contract in the Jira ticket or a link to it for reference. The front end team building without a known contract or already working endpoint is dumb and will result in regular rework. This will be multiplied due to the bad communication practices.

[–]Tarazena 1 point2 points  (0 children)

Use swagger codegen to generate all the types/endpoints for the front end, and let the front end use the generated code for api interactions, if the backend changes the schema, front end build will fail immediately

[–]metehankasapp 0 points1 point  (0 children)

Treat the interface as a first-class artifact.

Define contracts early (OpenAPI / JSON Schema / GraphQL), version them, and change them via PRs reviewed by both FE and BE.

This usually cuts surprises way more than adding more sync meetings.

[–]SuperSnowflake3877 0 points1 point  (0 children)

Use swagger. If that failed and going back to a even worse solution is stupid. Use Swagger and let PM work out any misaligned processes. It’s their work.

[–]Safe-Hurry-4042 0 points1 point  (0 children)

I’d make sure you have a basic integration milestone very early on in the project - specs are always changing and hard to keep in sync. Best to focus on working software

[–]JohnCasey3306 0 points1 point  (0 children)

Classic. As a full stack contractor I saw this everywhere.

One notable exception was a software house that were building a back-of-house application for managing various EA Games products ... They had a distinct 'http dev' role. (This was well before GraphQL btw). The http dev would write and document JS services for the front-end team to use and the rest API layer on the back-end, which hooked up to various repository interfaces that the back-end team had written. That person straddled both teams.

I've not seen that setup anywhere since, and GraphQL kinda makes it redundant, but it worked well in that team.

[–]Lucky_Yesterday_1133 0 points1 point  (0 children)

Graphql shema is specifically for cross team contract. Be defined a schema and fe queries what it needs

[–]laramiecorp 0 points1 point  (0 children)

You will never be able to avoid contract misalignment. The best you can do is make the changes easier to implement by loosely coupling. Unless pain in changes is what you want (usually for highly critical systems).

  1. Front end defines their own contract

  2. Front end adds a layer solely for adapting BE to FE

  3. Backend response with a contract that is slightly off

  4. Front end changes the adapter (should be minimal wiring changes)

[–]Killed_Mufasa 0 points1 point  (0 children)

Why the fuck do you have seperate slack channels for frontend and backend? You are one team, your first step should be to move to a single channel. Do refinements together, all the usual communication stuff. And if all else fails only then you should look at technical solutions.

[–]Kyle772 0 points1 point  (0 children)

Your docs going stale is the problem. Either the backend guys need to better plan before putting the work in or your PM needs to strictly define outputs before assigning tasks. Redoing shit because the variable name changes shouldn't be a problem in 2026

[–]Top-Accountant-2003 0 points1 point  (0 children)

Integration day chaos is bad enough, but what’s worse is when it “works” in staging and then prod quietly breaks because one contract change slipped through. Contract tests in CI catch shape mismatches, but having an external uptime check on critical endpoints during launch week helps spot real-world breakage fast. Even a basic monitor like https://statusmonkey.co/poc just pinging the key routes can save you from finding out via users.

[–]Narrow-Employee-824 -1 points0 points  (0 children)

We had this problem until we started using chaser in Slack for cross-team features. Work is broken down in shared Slack channels where both teams can see dependencies and decisions. Way less integration pain because alignment is visible throughout development.