Skip to content

Exhaustive OData Navigation Path Generation creates unusable specification #122

@christopinka

Description

@christopinka

OpenAPI Spec is 35MB Due to Exhaustive OData Navigation Path Generation

Problem

The generated OpenAPI spec (v1.0) is 35MB with 10,405 paths, making it unusable in API clients (Insomnia, Postman, Swagger UI). The root cause is that the spec includes every possible navigation path through the object graph, not just useful endpoints.

Example of Path Explosion

A single resource like /drives/{id}/items/{id} generates 1,505 paths because it includes every nested relationship:

  • /drives/{id}/items/{id} - the actual file (useful)
  • /drives/{id}/items/{id}/createdByUser - navigate to creator
  • /drives/{id}/items/{id}/createdByUser/manager - creator's manager
  • /drives/{id}/items/{id}/createdByUser/manager/directReports/{id} - manager's team
  • /drives/{id}/items/{id}/createdByUser/manager/directReports/{id}/photo - their photos
  • ... continues 5-10 levels deep

Reality Check: Nobody uses /drives/{id}/items/{id}/createdByUser/manager/photo - they'd call /users/{id}/photo directly. These navigation paths are technically valid in OData but practically useless.

Analysis

  • 10,405 paths (most are nested navigation bloat)
  • 4,292 schemas (3,242 unused - 75%)
  • 1,157 responses (521 unused - 45%)
  • 2,360 examples (all unused)

Impact

  • Clients freeze/crash loading the spec
  • Impossible to explore the API effectively
  • Poor developer experience
  • Forces developers to use Graph Explorer instead of standard OpenAPI tooling

Why Automated Filtering is Insufficient

The redundancy problem cannot be solved by consumers without Microsoft's domain knowledge and usage data.

Example ambiguity:

  • Is /drives/{id}/createdByUser/manager/photo a useful convenience path for "show file creator's manager" workflows, or should developers use /users/{id}/photo directly?
  • Is /groups/{id}/members/{id}/drive a common pattern for "list group members with their drives", or should it be two separate API calls?

Without access to:

  1. Usage telemetry - Which paths are actually called in production?
  2. Product intent - What workflows are officially supported?
  3. Performance data - Which paths cause expensive joins or should be discouraged?

...consumers cannot reliably determine which of the 10,405 paths are essential vs. redundant.

Proposed Solutions

Option 1: Publish filtered variants (Recommended)

Provide multiple spec files based on Microsoft's internal usage data:

  • openapi-core.yaml - Essential operations only (~500-1000 paths)
  • openapi-files.yaml - File operations (drives/sites/shares)
  • openapi-users.yaml - Identity (users/groups)
  • openapi-mail.yaml - Mail/calendar
  • openapi-full.yaml - Complete spec (current)

Option 2: Add navigation metadata

Mark paths in the spec with navigation type so consumers can filter:

paths:
  /users/{id}:
    x-ms-navigation-type: primary
  /drives/{id}/createdByUser:
    x-ms-navigation-type: convenience

Option 3: Provide official filtering tooling

Publish a tool that generates custom filtered specs based on use case (e.g., "file operations only", "exclude deep navigation").

Option 4: Document recommended patterns

Clearly document which navigation patterns are recommended vs. which exist only for OData compliance.

Proof of Concept

Filtering to just essential file operations (21 paths) reduces the spec from 35MB to 1.1MB - a 97% reduction while maintaining full functionality.

Comparison to Other APIs

  • AWS API Gateway: ~2MB for 200+ services
  • Stripe: ~500KB for complete API
  • GitHub: ~1.5MB for 600+ endpoints
  • Microsoft Graph: 35MB for effectively ~500 useful endpoints

Request

Provide a usable OpenAPI spec that works with standard tooling. The current spec is technically complete but practically unusable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions