Skip to content

Conversation

@OJEM22
Copy link
Collaborator

@OJEM22 OJEM22 commented Nov 20, 2025

Description

Implements a comprehensive GraphQL API for querying GTFS transit data using Strawberry GraphQL. This provides a modern, flexible alternative to the REST API with support for nested queries, field selection, pagination, and geographic search. The implementation includes 8 GraphQL types covering all major GTFS entities, 20+ query resolvers, comprehensive documentation (750+ lines), demo queries, and a full test suite (219 lines).

Type of Change

  • New feature (MINOR)
  • Bug fix (PATCH) - Fixed app naming conflict
  • Documentation update

Transportation Context

  • GTFS data handling
  • Data analysis enhancement
  • API endpoint modification

Testing

  • Unit tests added/updated - gql/tests.py (219 lines)
  • Integration tests pass - GraphQL queries tested end-to-end
  • Manual testing completed - GraphiQL interface tested with multiple query patterns

Test Execution:

python manage.py test gql

Test Coverage:

  • ✅ Query execution validation
  • ✅ Schema structure tests
  • ✅ Endpoint accessibility tests
  • ✅ GTFS model fixtures
  • ✅ Error handling tests
  • ✅ Pagination functionality tests

Documentation

  • Code comments updated
  • API documentation updated - Complete gql/README.md (750+ lines)
  • README.md updated - Added GraphQL API section with quick example
  • CHANGELOG.md updated - Comprehensive entry following Keep a Changelog format

TRL Impact

Current TRL: 6 → New TRL: 6 (no change)

Justification: This feature adds a new API interface but does not fundamentally change the system's technology readiness level. The GraphQL API provides an alternative query interface to existing GTFS data without modifying core transit data processing capabilities. While it enhances developer experience and query flexibility, it represents an incremental improvement rather than a readiness level advancement.


Detailed Changes

New Features

GraphQL API (/gql/ endpoint)

  • Modern GraphQL Interface: Alternative to REST API with enhanced query capabilities
  • Interactive GraphiQL: Browser-based visual query builder for API exploration
  • 8 GraphQL Types: GTFSProvider, Agency, Stop, Route, Trip, StopTime, Calendar, GeoShape
  • 20+ Query Resolvers: Multiple access patterns for flexible data retrieval
    • Basic entity lookups by ID
    • Paginated list queries
    • GTFS code-based lookups
    • Geographic proximity search (stopsNear)
    • Filtered queries by relationships
  • Pagination: Connection pattern with PageInfo metadata (totalCount, hasNextPage, pageNumber, numPages)
  • Nested Queries: Single-request retrieval of related data (e.g., routes → trips → stops)
  • Geographic Search: PostGIS spatial queries for finding stops within radius
  • Performance Optimization: ORM query optimization with select_related() and prefetch_related()
  • Self-Documenting: GraphQL introspection for automatic documentation

Documentation

  • gql/README.md (750+ lines)

    • Complete API reference
    • Query examples for all resolvers
    • Integration examples (Python, JavaScript, cURL)
    • Performance optimization guidelines
    • GraphQL vs REST comparison
    • Troubleshooting guide
    • Architecture documentation
  • gql/DEMO_QUERIES.md

    • Curated real-world query examples
    • Basic to advanced patterns
    • Geographic search demos
    • Complex nested query examples
  • CHANGELOG.md (NEW)

    • Created following Keep a Changelog format
    • Comprehensive GraphQL feature documentation
    • Technical implementation details
    • Future enhancements section
  • README.md Updates

    • New GraphQL API section with quick example
    • Updated Application Structure
    • Updated Project Structure

Test Suite

  • gql/tests.py (219 lines)
    • Comprehensive test coverage
    • Query execution validation
    • Schema structure tests
    • Endpoint accessibility tests
    • GTFS model fixtures
    • Error handling tests
    • Pagination functionality tests

Technical Implementation

Schema Architecture

  • gql/schema.py: Strawberry Schema definition with Query type registration
  • gql/types.py (271 lines): Strawberry Django model types with field mappings, custom pagination types (Connection, PageInfo), relationship fields
  • gql/queries.py (265 lines): Query resolvers optimized with Django ORM

Django Integration

  • gql/apps.py: Django app configuration
  • datahub/settings.py: Added gql.apps.GqlConfig to INSTALLED_APPS
  • datahub/urls.py: Added GraphQL endpoint routing
  • GraphiQL interface enabled in development
  • ASGI/Daphne server compatibility maintained

Bug Fixes

  • App Naming Conflict: Renamed graphql/ directory to gql/ to avoid import collision with Python's graphql-core library (dependency of Strawberry)

Dependencies Added

  • strawberry-graphql==0.285.0 - GraphQL schema definition library
  • strawberry-graphql[django]==0.285.0 - Django integration for Strawberry
  • Updated uv.lock with new dependencies and dependency tree

Configuration

  • GraphQL endpoint: /gql/
  • GraphiQL interface accessible in browser (development mode)
  • ASGI server compatible
  • No additional environment variables required

Impact on System

Positive Impacts

  • Enhanced Developer Experience: Modern GraphQL interface with field selection and nested queries
  • Reduced API Calls: Single request can fetch related data across multiple entities
  • Flexible Querying: Clients request only needed fields, reducing bandwidth
  • Self-Documenting: GraphQL introspection provides automatic, accurate documentation
  • Geographic Capabilities: PostGIS integration enables spatial queries
  • Performance: Optimized resolvers prevent N+1 query problems

No Breaking Changes

  • GraphQL API is additive - all existing REST endpoints unchanged
  • Both APIs coexist and can be used independently
  • No modifications to existing functionality
  • Backward compatible with all clients

How to Test

Access GraphiQL Interface

# Start development environment
docker compose up

# Open browser
open http://localhost:8000/gql/

Run Test Suite

# Run all GraphQL tests
docker compose exec web python manage.py test gql

# Run with verbose output
docker compose exec web python manage.py test gql --verbosity=2

Example Queries

Basic Query:

query {
  hello {
    message
  }
}

Geographic Search:

query {
  stopsNear(lat: 9.9356, lon: -84.049, radiusKm: 0.5, page: 1, pageSize: 5) {
    edges {
      stopName
      stopLat
      stopLon
    }
    pageInfo {
      totalCount
    }
  }
}

Nested Query:

query {
  route(id: 1) {
    routeShortName
    routeLongName
    agency {
      agencyName
    }
    trips {
      tripHeadsign
      stops {
        stopName
        stopLat
        stopLon
      }
    }
  }
}

Integration Testing

Python:

import requests

query = """
query {
  stops(page: 1, pageSize: 5) {
    edges { stopName stopLat stopLon }
    pageInfo { totalCount }
  }
}
"""

response = requests.post(
    "http://localhost:8000/gql/",
    json={"query": query},
    headers={"Content-Type": "application/json"}
)
print(response.json())

References

  • Related Issue: GraphQL API integration feature
  • Dependencies: Strawberry GraphQL 0.285.0, Strawberry Django

Commits in This Branch

  1. 78c9634 - docs(gql): add CHANGELOG and update README with GraphQL API documentation
  2. 7726886 - fix(gql): rename graphql app to gql to avoid naming conflict
  3. 6a4bef8 - docs(gql): add comprehensive documentation and demo queries
  4. 5b920ae - refactor(gql): rename gql_schema to graphql and convert to Django app
  5. 96ad2c1 - chore(gql): update uv.lock with Strawberry GraphQL dependencies
  6. 3e5f6fd - feat(gql): complete GraphQL schema with GTFS core models and pagination
  7. 145f7d1 - feat(gql): add GraphQL support with Strawberry Django integration

Checklist

  • All tests passing (gql test suite: 219 lines)
  • Documentation complete (README, CHANGELOG, gql/README.md, gql/DEMO_QUERIES.md)
  • CHANGELOG.md updated following Keep a Changelog format
  • README.md updated with GraphQL API section
  • GraphiQL interface tested and working
  • Query resolvers optimized with ORM best practices
  • Pagination implemented using Connection pattern
  • Geographic search validated with PostGIS
  • Demo queries tested and documented
  • Integration examples provided (Python, JavaScript, cURL)
  • Code follows project conventions (Conventional Commits)
  • No breaking changes to existing APIs
  • Ready for review and merge

Reviewers: Please Verify

  1. GraphiQL Interface: Access http://localhost:8000/gql/ and verify interactive interface works
  2. Test Suite: Run python manage.py test gql - all tests should pass
  3. Documentation: Review gql/README.md for completeness and accuracy
  4. Query Examples: Test demo queries from gql/DEMO_QUERIES.md in GraphiQL
  5. Geographic Search: Verify stopsNear query with sample coordinates
  6. Nested Queries: Test multi-level nested queries (route → trips → stops)
  7. Pagination: Verify pagination works correctly with page and pageSize parameters
  8. CHANGELOG: Confirm CHANGELOG.md follows Keep a Changelog format
  9. README: Verify README.md GraphQL section is clear and helpful
  10. No Regressions: Confirm existing REST API endpoints still work

Future Enhancements

  • Mutations for data modification (currently read-only)
  • Real-time subscriptions for live data updates
  • Authentication and authorization integration
  • Query complexity limits and depth restrictions
  • DataLoader integration for batch loading optimization
  • Rate limiting specific to GraphQL endpoint
  • Metrics and monitoring for GraphQL queries

Ready for Production: ✅ Yes
Backward Compatible: ✅ Yes
Breaking Changes: ❌ None
Documentation Complete: ✅ Yes

OJEM22 and others added 7 commits November 13, 2025 09:40
Implement comprehensive GraphQL API for GTFS core entities with nested
queries, pagination, and geo-spatial search capabilities.

Schema and Resolvers:
- Define GraphQL types for Stop, Route, Trip, StopTime
- Add types for Calendar, GeoShape, Agency, GTFSProvider
- Implement relationship resolvers for nested queries:
  * routes → trips → stops
  * stops → routes → stop_times
  * trips → route → service → stop_times
- All resolvers use Django ORM with select_related/prefetch_related

Pagination:
- Implement Connection pattern with PageInfo
- Pagination for: agencies, stops, routes, trips, stop_times
- PageInfo includes: has_next/previous, cursors, total_count, page numbers

Additional Features:
- Geo-spatial search: stops_near(lat, lon, radius_km) using PostGIS
- GTFS code lookups: agency_by_code, stop_by_code, route_by_code, trip_by_code
- Filtered queries: routes_by_agency, trips_by_route, stop_times_by_trip/stop
- Performance optimizations for nested queries

Test Coverage:
- Extended fixtures for Route, Calendar, Trip, StopTime
- Query execution and validation tests
- Schema conformance verification
- Endpoint accessibility tests

Issue #35: GraphQL Base Setup + Schema and Resolvers for Core Models
Update lock file to include GraphQL packages after rebase:
- graphql-core 3.2.7
- lia-web 0.2.3
- strawberry-graphql 0.285.0
- strawberry-graphql-django 0.67.0

This completes the dependency resolution for Issue #35 GraphQL integration.
Rename package from gql_schema to graphql for consistency with project
naming conventions (api, alerts, gtfs, etc.) and convert to proper Django app.

Changes:
- Rename gql_schema/ → graphql/ directory
- Create graphql/apps.py with GraphqlConfig class
- Update graphql/__init__.py with app config and documentation
- Add graphql.apps.GraphqlConfig to INSTALLED_APPS in settings
- Update all imports (datahub/urls.py, demo_graphql.py)

Benefits:
- Consistent with project naming (no underscores, no abbreviations)
- Proper Django app structure (recognized by manage.py commands)
- Better documentation and discoverability
- Can have migrations/models/management commands if needed later
- More professional Django convention

Addresses feedback to make GraphQL its own app.
Add complete documentation for GraphQL API implementation including
README with full API reference and DEMO_QUERIES with ready-to-use examples.

Documentation includes:
- Complete API overview and quick start guide
- 8 GraphQL type definitions with all fields and relationships
- 20+ query examples covering all resolver patterns
- Pagination, geographic search, and nested query examples
- Integration examples (Python, JavaScript, cURL)
- Testing guide and troubleshooting section
- Architecture and technology stack details
- GraphQL vs REST comparison

Demo queries file provides:
- 20 ready-to-paste queries for GraphiQL testing
- Basic queries (hello, agencies, stops, routes, trips)
- Geographic queries (stops_near with different radii)
- Nested queries (route→trips→stops, stop→schedule)
- Complex dashboard queries
- Performance testing queries
- Field selection demonstrations
- Testing checklist and modification tips

Benefits:
- Self-service documentation for API users
- Quick testing and validation
- Presentation-ready examples
- Integration guidance for developers
BREAKING: Rename GraphQL Django app from 'graphql' to 'gql' to prevent
import collision with Python's graphql-core library.

Issue:
When starting Docker containers, Django failed to import strawberry_django
because the 'graphql' app name conflicted with the 'graphql' package from
graphql-core (Strawberry's dependency). This caused import errors during
Django setup.

Root cause:
Python's module resolution found our 'graphql' Django app instead of the
'graphql' package from graphql-core, breaking Strawberry's imports.

Solution:
Rename app to 'gql' (short, clear, no conflicts):
- graphql/ → gql/ directory
- GraphqlConfig → GqlConfig class
- Update all imports and references
- Update documentation

Changes:
- Rename directory: graphql/ → gql/
- gql/apps.py: GraphqlConfig → GqlConfig, name='gql'
- gql/__init__.py: Update default_app_config path
- datahub/settings.py: graphql.apps.GraphqlConfig → gql.apps.GqlConfig
- datahub/urls.py: from graphql.schema → from gql.schema
- demo_graphql.py: Update import path
- gql/README.md: Update all references to app name and paths
- gql/DEMO_QUERIES.md: No changes needed (queries unchanged)

Benefits:
- Resolves Docker startup error
- No naming conflicts with Python packages
- Still clear and concise (gql is common abbreviation for GraphQL)
- Consistent with commit scope naming convention

Fixes Docker import error that prevented containers from starting.
…tion

- Create CHANGELOG.md following Keep a Changelog format
- Document GraphQL API feature in [Unreleased] section
- Add GraphQL API section to README with quick example
- Update Application Structure and Project Structure to include gql app
- Comprehensive technical implementation and dependency documentation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants