Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What If GraphQL Knew Accessibility

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for apidays apidays PRO
February 07, 2026

What If GraphQL Knew Accessibility

"About this Session: Accessibility is often treated as a ""final coat of paint,"" leading to fragmented user experiences across platforms. Vanessa Johnson (Android Engineer at The New York Times) proposes a radical shift: embedding accessibility metadata directly into GraphQL schemas.

Using custom directives and code generation, this approach enables mobile and web clients to receive accessible defaults—such as content descriptions and roles—directly from the API contract. This session provides a technical blueprint for making inclusivity a core part of the developer experience (DevEx) rather than an afterthought.

Key Takeaways:
• API-First Accessibility: Learn to encode accessibility requirements directly into your API contract using GraphQL custom directives.

• Automated Metadata Delivery: See how code generation can deliver accessibility defaults to clients (Android, iOS, Web) automatically from day one.

• Cross-Platform Consistency: Strategies to ensure a unified accessible experience across Jetpack Compose and SwiftUI.

• Actionable Blueprints: Get access to schema snippets and a repository with working code examples to implement these strategies immediately.

------------------------------------

Conference Details:
Conference: apidays Paris 2025 | part of FOST 2025
Theme: The APIs meet AI conference: Innovation, Security, Sovereignty, Sustainability
Date: 9 - 11 December 2025 • CNIT Forest, Paris

--------------------------

Resources from apidays:
Join our upcoming conferences: https://www.apidays.global/
Read the latest API news: https://www.apiscene.io
Explore the API Landscape: https://apilandscape.apiscene.io/"

Avatar for apidays

apidays PRO

February 07, 2026
Tweet

More Decks by apidays

Other Decks in Technology

Transcript

  1. What if GraphQL Knew Accessibility? Dynamic Accessibility Summaries with Directives

    apidays Paris 2025 December 911, 2025 Vanessa Johnson
  2. Impact Why This Work Vanessa Johnson Android Engineer The New

    York Times Make accessibility a first class citizen in API design. Can work across Android, iOS, and Web teams. Believe that programmatic accessibility metadata can bridge the gap between API design and inclusive user experiences, making the user experience better for everyone. About Me
  3. Why Accessibility Matters The invisible user base we can't afford

    to ignore 1.3B People with disabilities globally 16% of world population 71% Leave inaccessible sites immediately Lost customers due to poor UX 3% Of the web is fully accessible WebAIM Million 2025 report
  4. The Accessibility Gap in APIs How APIs shape user experience

    long before UI code is written APIs Shape UX First Data structure determines user flow APIs define what information is available and how it's organized, and influence UI decisions before designers even start. Accessibility Added Last An afterthought in development Accessibility is typically addressed during UI implementation, long after API contracts are finalized. Inconsistent Implementation No standard approach Each team implements accessibility differently, leading to inconsistent experiences across platforms.
  5. APIs Today: What We Get Standard GraphQL query without accessibility

    metadata GraphQL Query query Movie { movie(id: "1") { title releaseYear rating } }
  6. Pain Points The challenges of retrofitting accessibility Leaving components without

    a11y labels “Unlabeledˮ Missing information that will be needed by screen readers to help users use your product. Inconsistent Across Platforms Android ≠ iOS  Web Each platform team implements accessibility differently, creating divergent experiences for the same data. The Result: Fragile, Inconsistent Accessibility Every platform reinvents accessibility labels, leading to drift, bugs, and inconsistent screen reader experiences. This creates a maintenance nightmare as APIs evolve and teams scale.
  7. The Client Info Flow Problem Developers handcraft fragile accessibility phrases

    Kotlin Example val summary = "${movie.title}, ${movie.releaseYear}, rated ${movie.rating}/10" String Building is Fragile Hardcoded templates break when data changes, localization needed, or edge cases emerge. Duplicated Logic Same pattern repeated across Android, iOS, Web teams with slight variations. Inconsistent Results Screen readers hear different summaries for the same content depending on platform.
  8. The Cost of Doing Nothing Why accessibility is a business

    imperative, not just a compliance checkbox Abandonment Disabled users leave difficult sites immediately Lost customers & revenue Monetary Settlements Per accessibility lawsuit Legal risk & compliance SEO Traffic Gain From accessible, structured content Discoverability & reach The Business Case is Clear Accessibility isn't just about compliance, it's about market expansion, brand reputation, and reducing risk. Companies that invest in accessibility see measurable returns across customer satisfaction, conversion rates, and operational efficiency.
  9. Initial Schema Without A11y) Basic Movie type with no accessibility

    metadata GraphQL Schema type Movie { title: String! releaseYear: String! rating: Float! }
  10. Shifting Left: The Vision Make accessibility part of the API

    contract, not a frontend afterthought Encode Semantics Embed accessibility metadata directly in GraphQL schema using custom directives Generate Types Create strongly typed models that carry a11y metadata to clients Deliver Defaults Provide accessible labels, tokens, and templates to all platforms from day one "Accessibility should be baked into the API, not sprinkled on top of the UI later."
  11. Schema Wiring Inject a11y Add per field hints Schema +

    Directives Enhanced Schema Response summary: “The movie Inception, released on 2010-07-16, is rated 8.8 out of 10." Custom Wiring Plugin
  12. Core Idea: Embed Accessibility Metadata Use GraphQL directives to annotate

    types and fields with accessibility information @a11yLabel Declare which field is the main label for screen readers @a11yToken Structured data type with priority, units, and formatting @a11yTemplate Sentence template with placeholders for consistent phrasing The Goal: Consistent, Accessible Experiences Clients assemble labels, tokens, and templates to generate reliable, localized summaries for screen readers. One schema change → consistent accessibility across all platforms.
  13. @a11yLabel Directive Declare the primary label for screen readers GraphQL

    Schema What It Does Tells screen readers which field contains the primary, human readable label for this object. Why It Matters Provides the main identifier that screen readers announce first when users encounter this object. Usage Pattern Applied to the object type, not individual fields, points to the field that best represents the object. directive @a11yLabel(field: String!) on OBJECT | FIELD_DEFINITION type Movie @a11yLabel(field: "title") { title: String! releaseYear: String! rating: Float! }
  14. @a11yToken Directive Structured data type for screen readers with priority

    and formatting GraphQL type + field The data type and field name this token represents (e.g., "price", "rating", "date"). priority 0..n Order of importance for screen readers. Lower values = higher priority. Default: 0. unitPrefix / unitSuffix Format numbers with currency symbols, percentages, or unit labels (e.g., "$", "/10", "GB"). number: Boolean Treats the value as a number for proper screen reader pronunciation (e.g., "299" vs "two nine nine"). directive @a11yToken( type: String! field: String! priority: Int = 0 label: String labelPosition: String unitPrefix: String unitSuffix: String number: Boolean ) on FIELD_DEFINITION
  15. @a11yTemplate Directive Sentence template with dynamic placeholders GraphQL Schema Template

    Placeholders Use {fieldName} syntax to reference schema fields in the template. Natural Language Template creates human readable sentences that screen readers can speak naturally. Dynamic Assembly Runtime substitution ensures summaries stay current with changing data. directive @a11yTemplate(summary: String) on OBJECT type Movie @a11yTemplate(summary: "{title}, {releaseYear}, rated {rating}/10") { title: String! releaseYear: String! rating: Float! }
  16. Complete Schema Example With A11y) Full implementation with all three

    directives and generated types type YourType @a11yTemplate(summary: "{name}, {price}") { name: String! @a11yLabel(field: "name") @a11yToken(type: "name", field: "name", priority: 0) price: Float @a11yToken( type: "price", field: "price", priority: 1, unitPrefix: "$", number: true ) a11y: A11y! } type A11y { label: String! tokens: [A11yToken!] templates: A11yTemplates } type A11yToken { type: String! value: String! priority: Int! } type A11yTemplates { summary: String }
  17. Query Structure Requesting accessibility metadata alongside regular data GraphQL Query

    Clients request regular data plus a nested a11y object that contains all accessibility metadata. The a11y field provides comprehensive accessibility information query Product$id: ID!) { product(id: $id) { name price a11y { label tokens { type value priority } templates { summary } } } }
  18. Response Structure With A11y) How clients receive accessibility metadata alongside

    regular data JSON Response { "product": { "name": "Noise-Canceling Headphones", "price": 299.0, "a11y": { "label": "Noise-Canceling Headphones", "tokens": [ { "type": "name", "value": "Noise-Canceling Headphones", "priority": 0 }, { "type": "price", "value": "299", "priority": 1 } ], "templates": { "summary": "Noise-Canceling Headphones, $299" } } } }
  19. Response Structure With A11y) Label Main screen reader label Tokens

    Structured data with priority Templates Sentence assembly pattern
  20. Android Example Jetpack Compose) Using generated a11y metadata with Jetpack

    Compose Kotlin/Jetpack Compose Composable fun ProductCard(product: Product) { Column( modifier = Modifier.semantics { contentDescription = product.a11y.templates.summary } ) { Text(product.name) Text("$" + product.price) } } Key Features • Uses generated a11y.templates.summary field • Direct semantic mapping from API • Consistent with schema definition Accessibility Benefits • Screen readers get meaningful hints • No manual string building needed • Platform agnostic implementation
  21. iOS Example SwiftUI Using accessibility metadata in SwiftUI components SwiftUI

    Code SwiftUI automatically uses the a11y.templates.summary for Voice Over announcements. Provides consistent accessibility across all Apple platforms. struct ProductView: View { let product: Product var body: some View { VStack(alignment: .leading) { Text(product.name) .font(.headline) Text(\"$\\(product.price)\") .font(.subheadline) } .accessibilityLabel(Text(product.a11y.templates.summary)) } }
  22. Web Example React Using a11y metadata in React components with

    ARIA attributes React Component React components can consume a11y metadata directly through aria-label attributes. The a11y.templates.summary provides a consistent, screen readable summary for the entire component. function ProductCard({ product }) { const { name, price, a11y } = product; return ( <div aria-label={a11y.templates.summary} role="group"> <h3>{name}</h3> <p${price}</p> </div> ); }
  23. Benefits & Impact What you get when accessibility becomes part

    of your API contract Single Source of Truth Removes Brittle Client Logic Dynamic Per Instance Summaries Optional Field Level Nuance Result: Consistent, accessible experiences across all platforms with less developer effort
  24. Ownership & Considerations Key questions and strategies for successful implementation

    Who Owns the Directives? 1 Product + Design collaboration Define semantic meaning and user experience 2 Backend engineers Implement directives and resolvers 3 Combination Collaboration of cross-functional teams Missing Metadata Strategy Sensible Fallbacks Use field names as fallback labels when a11y metadata is missing Monitoring Track missing a11y metadata and report gaps Gradual Adoption Start with critical fields, expand coverage over time
  25. Localization Strategy Template per Locale Use locale-specific templates in schema

    Server-Side Injection Inject localized strings at runtime Deferred Loading Load translations on demand Versioning & Compatibility Backward Compatibility New directives are optional, existing clients continue to work Schema Evolution Add new metadata fields without breaking changes Feature Flags Enable/disable a11y generation per client Ownership & Considerations Key questions and strategies for successful implementation
  26. Thank You! Questions? Let's continue the conversation github.com/vanessamj99/GraphQL-a11y LinkedIn Portfolio

    #a11y #APIs Vanessa Johnson - Android Engineer @ The New York Times GitHub