Case Study · 01

Redesigning the
Service Dependency Graph.

Rebuilding how engineers navigate thousands of API contract dependencies without losing their place.

Timeline
1 week
Team
Solo (design), handed off to engineering + QA
Role
Product Designer
Surface
Enterprise B2B · API contract observability
— AI summary

The condensed version.

Problem: Specmatic Insights' Service Dependency Graph shows how up to 5,000 services connect through API contracts, with only 12–24 visible on screen at once — but the existing graph broke down at that scale. Controls competed for space with the graph itself, navigation aids were either missing or permanently on screen regardless of need, and there was no fast way to find a specific service or understand where you were relative to the rest of the system. Solution: The reframe was from "show every control, all the time" to "show the graph, and let controls earn their place on screen" — search, filters, a directional pad, and a minimap all still exist, but now appear based on what the user is actually doing rather than living in a fixed toolbar. Impact: This design was handed off for usability and QA testing, so what follows are concrete before→after design changes rather than tested metrics — toolbar actions cut from 8+ competing controls to the 7 that directly support finding, understanding, or navigating a service, and the graph promoted from a bounded dashboard card to a fullscreen-capable primary workspace.

The throughline: the real work was deciding which controls hadn't earned their place on screen, not making the existing ones prettier. Conditional UI — navigation aids that appear only once the graph's complexity justifies them — did more for the interface than any single new feature would have.

01 Quick Summary

Problem, solution, and the impact being tested.

01

Problem

Specmatic Insights includes a Service Dependency Graph that shows how services connect to each other through API contracts — not infrastructure, but logical provider–consumer relationships. At the scale the product needed to support (roughly 100–5000 services, with only 12–24 visible on screen at once), the existing graph broke down. Controls competed for space with the graph itself, navigation aids were either missing or permanently on screen regardless of need, and there was no fast way to find a specific service or understand where you were relative to the rest of the system.

02

Solution

The reframe was from "show every control, all the time" to "show the graph, and let controls earn their place on screen." Three moves carried that through:

  1. 01Simplify the toolbar — cut from 8+ competing controls down to the 7 that map directly to finding, understanding, or navigating a service.
  2. 02Make navigation contextual — the directional pad and minimap appear only once zoom and node-count cross a threshold, instead of being always-on or missing entirely.
  3. 03Treat fullscreen as exploration — the same navigation controls and an explicit exit path carry through from dashboard card to fullscreen.
03

Impact

This design was handed off for usability and QA testing, so what follows are the concrete before→after design changes, not tested metrics:

  1. 01Toolbar cut from 8+ controls to 7 — View dropdown, Prev, Next, and Export removed; what's left maps directly to finding, understanding, or navigating a service.
  2. 02Navigation moved from binary to conditional — the directional pad and minimap now appear only above a zoom/node-count threshold, instead of always-on or missing.
  3. 03Graph promoted to a fullscreen-capable workspace — without losing the surrounding Insights dashboard context.
  4. 04Search narrowed by ~20% — reads as a fast path to a service rather than a dominant toolbar element competing with the graph.
02 Preview

The redesign, live.

Open the interactive prototype
An interactive prototype of the redesigned graph — the toolbar, contextual navigation, and fullscreen mode described below, actually working. Opens in Figma, in a new tab.
03 Context

The scale wasn't hypothetical.

Specmatic helps engineering teams verify that services actually communicate the way their API contracts say they will — and the Service Dependency Graph is the part of Insights that shows which services depend on which. It's used by developers, architects, QA, SREs, and engineers new to a codebase alike, each for a different job: find a service, assess blast radius, scope regression tests, or just get oriented. The intended scale — 100–5000 services, only ~12–24 visible at once — was the baseline from day one, not an edge case, which meant the graph's problems were structural, not cosmetic.

  1. What the product does. Specmatic helps engineering teams work with API contracts and verify that services actually communicate the way those contracts say they will. Insights is the visibility layer on top of that — and the Service Dependency Graph is the part of Insights that shows which services depend on which, a logical contract-relationship graph, not a runtime infrastructure map.
  2. Who relies on it. Not one type of user — backend/API developers, contract owners, platform engineers, architects, EMs, QA/test teams, DevEx/governance teams, SREs, and engineers new to a codebase all use this graph, each with a different job: find a service, assess blast radius, scope regression tests, understand ownership, or just get oriented in an unfamiliar system.
  3. Why the complexity is real, not invented. The intended scale is 100–5000 services with only ~12–24 visible at a time. That's not a hypothetical edge case — it's the baseline the graph has to work at from day one, which means "more services" reliably means "more relationships, more visual noise, harder navigation."
  4. Why this needed a redesign, not a visual refresh. The existing graph's problems weren't cosmetic. Nodes could exist with no visible relationships and no explanation why. The canvas didn't use its own space efficiently. Controls were permanently present regardless of whether the current view needed them. These are structural, information-hierarchy problems — repainting the same toolbar wouldn't have fixed any of them.
04 Simplifying the Toolbar

Controls should earn their place.

The toolbar carried a View dropdown, Prev/Next, and Export — controls unrelated to actually finding or understanding a service, competing for space with search, filters, and the graph itself. Instead of restyling the clutter, I removed anything that didn't map directly to find → understand → navigate → orient → focus, cutting the toolbar from 8+ controls to the 7 that earn their place, and narrowing search by roughly 20% so it reads as a fast path rather than a dominant element. The fix wasn't fitting the controls in more neatly — it was deciding which ones didn't belong there at all.

What the legacy approach made users do

The original graph toolbar carried a View dropdown, Previous and Next buttons, and an Export action — all competing for the same visual space as the graph itself, alongside search, filters, and the graph controls that actually mattered for navigation. A user opening the graph to answer "what does this service depend on?" had to visually filter out four controls that had nothing to do with that question before they could even start.

The obvious fix, considered and rejected

The easy move here would have been a visual refresh — restyle the same toolbar, tighten the spacing, call it done. That was set aside quickly: the problem wasn't that the controls looked cluttered, it was that they were cluttered with the wrong things. Restyling doesn't fix a control competing for space it hasn't earned.

The reframe

The real question wasn't "how do we fit these controls in more neatly" — it was "does this control directly help the user understand or navigate the dependency graph?" Anything that didn't clear that bar came out entirely, rather than being made smaller.

The result

View dropdown, Previous, Next, and Export were removed outright. What remained — total service count, search, zoom, fit, reset, filters, and the graph itself — earned its place because each one maps directly to a step in the actual user task (find → understand → navigate → orient → focus). Search was kept but narrowed by roughly 20%, sized as a fast path to a specific service rather than a dominant toolbar element. Filters were rebuilt as compact, canvas-anchored elements instead of a toolbar row, so the graph — not the chrome around it — stays the dominant visual element.

Screenshot: legacy toolbar vs. simplified toolbar
The legacy toolbar (View dropdown, Prev/Next, Export competing with search and filters) compared against the simplified version — 7 controls, each mapped to a step in the actual task.

Removing a control outright is a stronger move than restyling it. The question isn't how to fit everything in more neatly — it's what hasn't earned its place at all.

05 Contextual Navigation

When does a nav aid earn its space?

Navigation aids didn't track user context — a directional pad sat on screen regardless of zoom level, and no minimap existed at any zoom level. Instead of making both permanent, I made them conditional: the directional pad appears once the user is zoomed in, and the minimap only above 150% zoom and 50+ nodes — the two conditions under which someone is actually likely to lose spatial context. The question wasn't whether a nav aid should exist, but when it earns the screen space it takes.

What the legacy approach made users do

In the current build, navigation aids don't yet track the user's actual context. A directional control sits on screen at all times regardless of zoom level, and there's no minimap at any zoom level — so on a small graph the interface still carries navigation weight it doesn't need, while on a large, deeply-zoomed graph, there's nothing to answer "where am I relative to the rest of the system?"

The obvious fix, considered and rejected

The default pattern most graph tools reach for is a permanent minimap, always in the corner. That was ruled out — for a graph that's frequently small or simple, a permanent minimap is a second navigation layer the user doesn't need yet, and it takes up canvas space that could go to the graph itself.

The reframe

The guiding question became "when does a navigation aid actually justify the screen space it takes?" — not "should this feature exist," but "when should it appear." That produced two explicit, testable conditions instead of an always-on/never-on binary: the 4-key directional pad appears only once the user is sufficiently zoomed in, positioned just above the bottom toolbar with Down directly under Up so it reads as a deliberate controller, not a scattered set of arrows. The minimap appears only when zoom exceeds 150% and the graph has more than 50 nodes — the two conditions under which a user is genuinely likely to lose spatial context.

The result

Both aids go from either permanently present or entirely absent to conditionally available exactly when the graph's complexity justifies them — small and simple graphs stay clean, while large, zoomed-in graphs get the orientation support they need without that support existing as visual noise the rest of the time.

Screenshot: directional pad + minimap appearing at threshold
The directional pad and minimap, appearing once zoom and node-count cross their respective thresholds — orientation support exactly when the graph's complexity justifies it.

Conditional UI needs an explicit, testable threshold — not a vague "show it when it's needed." A fuzzy rule is unbuildable and unreviewable; zoom >150% and >50 nodes is neither.

06 Fullscreen as an Exploration Mode

An exploration mode, not a magnification setting.

The graph was bound by the surrounding page, so real exploration — following a long dependency chain, comparing spread-out clusters — meant working in a canvas smaller than the problem it represented. Simply enlarging the canvas wasn't enough without carrying navigation controls and a clear exit path into it, so fullscreen became a deliberate escalation path: Normal → Graph section → Fullscreen, with the same bottom navigation, fit, and reset controls as the standard view. Fullscreen needed to be an exploration mode, not just a magnification setting.

What the legacy approach made users do

The graph was bound by the surrounding webpage. Any real exploration — following a long dependency chain, comparing spread-out clusters — meant working inside a canvas that was smaller than the problem it was trying to represent, with no way to reclaim more space.

The obvious fix, considered and rejected

The straightforward version of "give it more room" is simply making the graph bigger — expand the card, shrink the surrounding page. That alone wasn't enough: making the canvas bigger without carrying navigation controls (fit, reset, zoom) and a clear exit path into that bigger view just relocates the original problem into a larger box.

The reframe

The distinction that mattered was fullscreen as an exploration mode, not a magnification setting. Going fullscreen needed to preserve every navigation aid the user relies on in the normal view — bottom navigation, fit, reset — and needed an unambiguous way back out, rather than trapping the user in an enlarged canvas with no clear exit.

The result

The graph now supports Normal webpage → Graph section → Fullscreen graph as a deliberate escalation path. The Insights dashboard context stays intact until the user chooses to leave it, and fullscreen carries the same bottom navigation and recovery controls (fit/reset) as the standard view, with an explicit way to exit back to the dashboard.

Screenshot: graph section → fullscreen transition
The escalation path from dashboard card to fullscreen — every navigation control carried through, with an explicit way back out.

More screen space only helps if the controls and the exit path travel with it. A bigger canvas that strands the user is the same problem in a larger box.

07 Open Gaps

Naming the gaps honestly.

Reviewing the live graph against these decisions surfaced gaps worth naming honestly, since this design has been handed to testing rather than treated as finished:

  • Several service nodes (in the current data set: inventory-sync-service, catalog-service, customer-service, and others) render with no visible edges at all, with nothing in the UI explaining whether that's a real absence of dependencies or a data-loading gap — a meaningful trust issue in a graph whose entire purpose is showing relationships.
  • The directional pad currently renders before any zoom interaction happens, which doesn't yet match the "appears only when zoomed in" rule it was designed around — worth confirming whether this is a build gap or an intentional simplification for the test build.
  • There's no visible zoom-level indicator, and no breadcrumb showing which repo/contract path is currently in scope — both of which matter for a user trying to confirm they're looking at the right dataset.

Flagging these here rather than glossing over them is part of what this design is being tested for.

08 Team Dynamics

Left open, on purpose.

This section is intentionally left open. The real friction moment — a disagreement, a decision that got walked back, or a constraint worked within — belongs here once it's written up, rather than being filled with something invented.

09 Conclusion

Craft lessons, and one deeper one.

Craft lessons

  • Removing a control outright is a stronger move than restyling it — the toolbar simplification only worked because it started from "does this help the core task," not "how do we fit this in more neatly."
  • Conditional UI needs an explicit, testable threshold (zoom >150% and >50 nodes), not a vague "show it when it's needed" — a fuzzy rule is unbuildable and unreviewable.
  • A graph's canvas efficiency matters as much as its controls — a beautifully simplified toolbar still fails the user if the graph underneath doesn't use its own space well, which is exactly what testing needs to catch here.

One deeper lesson. Progressive disclosure is easy to state as a principle and easy to violate by accident — the directional pad rendering before any zoom happened is a reminder that a design principle only holds if it's checked against the actual build, not just the intended interaction model.

— Extras

A few things worth naming.

  • Competitive research as a design input, not inspiration mining. Reviewed Cortex, OpsLevel, Port, Backstage, Datadog, Kiali, LeanIX, Ardoq, Structurizr, and others specifically for navigation patterns, ownership display, and scalability approaches — not for visual style.
  • Contract-intelligence opportunities identified but not yet built. Provider vs. consumer distinction, contract health status, and breaking-change impact surfaced as clear next-step opportunities during competitive research, scoped out of this first pass to keep the week focused on navigation and structure.
  • A reusable progressive-disclosure pattern. The threshold-based approach to the minimap and directional pad (show only above a defined complexity threshold) is a pattern that could generalize to other dense-data views in Insights beyond this graph.