Skip to content

Latest commit

 

History

History
373 lines (317 loc) · 13.8 KB

File metadata and controls

373 lines (317 loc) · 13.8 KB

UK Legislation API Client - Master Plan

Project Overview

A comprehensive .NET 10 client library for the UK Government's Legislation API (legislation.gov.uk), following the proven patterns from the Uk.Parliament project. This library will provide 100% API coverage with full type safety, resilience, and extensive testing.

Current Status

Phase 1: Foundation & Core Setup - ✅ COMPLETE
Phase 2: Core Legislation API - ✅ COMPLETE
Phase 3: Type Safety with Enums - ✅ COMPLETE
Phase 4+: Planned - Ready to begin

What's Working Now

  • ✅ Full project structure with xUnit 3 testing
  • ✅ XML/Atom feed parsing (API uses XML, not JSON)
  • ✅ Live API integration verified
  • Type-safe enum-based API (LegislationType)
  • ✅ 26 tests passing, 1 skipped (documented limitation)
  • ✅ Comprehensive documentation (API_ENDPOINTS.md, README.md)
  • ✅ DI/IoC support with Polly resilience
  • ✅ All 37 legislation types enumerated with conversion utilities

Recent Achievements

  • Phase 3 Complete: Type-safe enum API implemented
  • LegislationTypeExtensions: ToUriCode(), FromUriCode(), TryFromUriCode()
  • Custom Refit Formatter: Automatic enum-to-string URL conversion
  • All Tests Updated: Using enums instead of string literals
  • 5 New Tests: Extension method validation (27 total tests)
  • README Rewrite: Comprehensive enum-based examples

Goals

  • 100% API Coverage: Support all legislation.gov.uk API endpoints and features
  • Type Safety: Leverage Refit for compile-time type-safe REST API access
  • Resilience: Implement Polly-based retry and circuit breaker policies
  • Testability: Comprehensive unit and integration test coverage using xUnit 3
  • Best Practices: Follow .NET coding standards, dependency injection patterns, and async/await
  • Documentation: XML documentation for all public APIs
  • NuGet Ready: Package metadata, versioning, and release automation

Technology Stack

Core Framework

  • .NET 10 (latest LTS)
  • C# 14.0 with nullable reference types enabled
  • Refit 8.x for type-safe HTTP API clients
  • System.ServiceModel.Syndication for Atom feed parsing
  • Microsoft.Extensions.DependencyInjection for IoC/DI support
  • Polly for resilience and transient-fault-handling

Testing

  • xUnit 3.x - Testing framework (using xunit.v3 package)
  • AwesomeAssertions - Fluent assertion library (NOT FluentAssertions)
  • AwesomeAssertions.Analyzers - Compile-time assertion validation
  • Moq 4.x - Mocking framework for unit tests
  • Coverlet - Code coverage analysis

Build & Release

  • Nerdbank.GitVersioning - Automated semantic versioning
  • Microsoft.SourceLink.GitHub - Source code debugging support
  • EditorConfig - Consistent code style enforcement

UK Legislation API Structure

API Endpoints & Features

Based on the developer documentation at https://www.legislation.gov.uk/developer/contents:

1. Legislation Types Supported

All 37 types enumerated in LegislationType enum:

  • UK Public General Acts (ukpga)
  • UK Local Acts (ukla)
  • UK Private and Personal Acts (ukppa)
  • Acts of the Scottish Parliament (asp)
  • Acts of Senedd Cymru (asc)
  • Measures of the National Assembly for Wales (mwa)
  • Church Measures (ukcm)
  • Acts of the Northern Ireland Assembly (nia)
  • UK Statutory Instruments (uksi)
  • Wales Statutory Instruments (wsi)
  • Scottish Statutory Instruments (ssi)
  • Northern Ireland Statutory Rules (nisr)
  • Church Instruments (ukci)
  • UK Ministerial Directions (ukmd)
  • UK Ministerial Orders (ukmo)
  • European Union Regulations (eur)
  • European Union Decisions (eudn)
  • European Union Directives (eudr)
  • Draft Legislation (ukdsi, sdsi, nidsr)
  • Impact Assessments (ukia)
  • And more historical types...

2. Core API Capabilities

A. Retrieval APIs ✅ IMPLEMENTED
  • Get legislation by URI (e.g., /ukpga/2020/1/data.xml)
  • Get legislation metadata (via XML parsing)
  • Get Table of Contents (/contents/data.xml)
  • Get specific sections/schedules/articles (Not available in API)
  • Get provisions at specific dates (point-in-time) (/{date}/data.xml)
  • Get extent information (in XML metadata)
B. Search API ⏳ PLANNED (Phase 3)
  • Full-text search across all legislation
  • Filter by:
    • Type (primary/secondary/EU-origin/draft/impact assessments)
    • Year/year range
    • Number
    • Title keywords
    • Modified/enacted date ranges
    • Geographical extent
    • Subject matter
  • Pagination support
  • Sort options
C. Feed APIs (Atom) ✅ IMPLEMENTED
  • Type-specific feeds (/{type}/data.feed)
  • Year-specific feeds (/{type}/{year}/data.feed)
  • Parsed to PagedResponse<LegislationItem>
D. Format Support
  • HTML - Human-readable web format ✅ Supported
  • XML - Structured legislation markup (CLML) ✅ Primary format
  • Atom - Feed format for updates ✅ Implemented
  • RDF/Turtle/N3 - Linked data formats ⏳ Planned
  • JSON - Not supported by API
  • PDF - Document format (where available) ⏳ Planned

3. URI Structure

Pattern: /{type}/{year}/{number}[/{date}][/data.{format}]

Examples:

  • /ukpga/2020/1/data.xml - UK Public General Act 2020 No. 1
  • /ukpga/2020/1/2021-01-01/data.xml - Point-in-time version
  • /ukpga/2020/1/contents/data.xml - Table of contents
  • /ukpga/2020/1/enacted/data.xml - As-enacted version
  • /ukpga/1998/data.feed - Atom feed for year

4. Key Features to Implement

Versioning & Point-in-Time ✅ IMPLEMENTED
  • Access legislation as originally enacted
  • Access current (revised) version
  • Access version at any specific date
  • Track amendments and changes
Geographical Extent ✅ MODEL CREATED, PARSING PENDING
  • England, Wales, Scotland, Northern Ireland
  • Extent information per provision
  • Territorial application queries
Effects & Impacts ⏳ PLANNED (Phase 7)
  • What legislation affects this item
  • What this legislation affects
  • Amendment tracking
  • Commencement information
Changes Timeline ⏳ PLANNED (Phase 6)
  • View all changes over time
  • Filter by change type (amendment, repeal, substitution)
  • Change metadata

Project Structure

Uk.Legislation/
├── .editorconfig                          # Code style rules ✅
├── .gitignore
├── README.md                              # ✅
├── MASTER_PLAN.md                         # This file ✅
├── API_ENDPOINTS.md                       # API documentation ✅
├── version.json                           # Nerdbank.GitVersioning ✅
├── Uk.Legislation.sln
│
├── Uk.Legislation/                        # Main library project
│   ├── Uk.Legislation.csproj             # ✅
│   ├── Icon.png                          # ✅
│   │
│   ├── Models/                           # Data models
│   │   ├── Common/
│   │   │   ├── LegislationType.cs       # ✅ All 37 types
│   │   │   ├── GeographicalExtent.cs    # ✅
│   │   │   └── PagedResponse.cs         # ✅
│   │   │
│   │   └── Legislation/
│   │       ├── LegislationItem.cs       # ✅
│   │       ├── LegislationMetadata.cs   # ✅
│   │       ├── TableOfContents.cs       # ✅
│   │       └── Provision.cs             # ✅
│   │
│   ├── Interfaces/                       # API contracts
│   │   └── ILegislationApi.cs           # ✅ 9 methods
│   │
│   ├── LegislationClient.cs              # ✅ Main client
│   ├── LegislationClientOptions.cs       # ✅ Configuration
│   │
│   ├── Extensions/                       # Extension methods
│   │   ├── ServiceCollectionExtensions.cs # ✅ DI support
│   │   ├── AtomFeedExtensions.cs        # ✅ Atom parsing
│   │   └── LegislationApiExtensions.cs  # ✅ Typed access
│   │
│   └── Exceptions/                       # Custom exceptions
│       ├── LegislationApiException.cs    # ✅
│       ├── LegislationNotFoundException.cs # ✅
│       ├── InvalidLegislationUriException.cs # ✅
│       └── HttpStatusResponseException.cs # ✅
│
├── Uk.Legislation.Test/                  # Test project
│   ├── Uk.Legislation.Test.csproj       # ✅
│   │
│   ├── UnitTests/
│   │   └── LegislationApiUnitTests.cs   # ✅ 9 tests
│   │
│   └── IntegrationTests/
│       ├── IntegrationTestBase.cs       # ✅
│       └── LegislationIntegrationTests.cs # ✅ 12 tests
│
└── Uk.Legislation.NuGet/                 # NuGet packaging
    └── Uk.Legislation.NuGet.csproj      # ✅

Implementation Phases

Phase 1: Foundation & Core Setup ✅ COMPLETE

Status: All objectives achieved

✅ Project Structure

  • Created solution with main library project
  • Created test project with xUnit 3 (using xunit.v3 package)
  • Created NuGet packaging project
  • Set up .editorconfig (copied from Uk.Parliament)
  • Configured Nerdbank.GitVersioning (v10.0)

✅ Core Dependencies

  • Added Refit 8.0.0 and Refit.HttpClientFactory
  • Added Microsoft.Extensions.Http 9.0.0 and Polly
  • Added System.ServiceModel.Syndication 10.0.0 for Atom feeds
  • Added test dependencies (xUnit 3.2.0, AwesomeAssertions 9.3.0, Moq 4.20.72)
  • Configured package metadata in .csproj

✅ Base Infrastructure

  • Implemented LegislationClientOptions with full configuration
  • Implemented base exception types (4 exceptions)
  • Created ServiceCollectionExtensions for DI (with and without resilience)
  • Set up XML documentation generation

Phase 2: Core Legislation API ✅ COMPLETE

Status: All objectives achieved + API format discovery

✅ Models - Basic

  • LegislationType enum (37 types with Description attributes)
  • LegislationFormat enum (Json, Xml, Html, Rdf, Pdf)
  • GeographicalExtent flags enum
  • LegislationItem (complete model)
  • LegislationMetadata (complete model)
  • TableOfContents + TocItem (hierarchical structure)
  • Provision (content model)
  • PagedResponse (generic pagination)

✅ API Interface - XML/Atom Based

  • ILegislationApi with 9 methods:
    • GetLegislationXmlAsync
    • GetLegislationAtDateXmlAsync
    • GetLegislationAsEnactedXmlAsync
    • GetProvisionXmlAsync (API limitation - returns 404)
    • GetTableOfContentsXmlAsync
    • GetLegislationByTypeFeedAsync
    • GetLegislationByTypeAndYearFeedAsync
    • GetLegislationHtmlAsync

✅ Client Implementation

  • LegislationClient with both constructor patterns
  • HttpClient configuration with proper headers
  • Refit integration for string responses
  • Error handling via exceptions

✅ Extension Methods

  • AtomFeedExtensions for parsing Atom feeds
  • LegislationApiExtensions for typed access
  • Proper handling of legislation.gov.uk namespaces

✅ Unit Tests (9 tests - all passing)

  • Mock-based tests for each API method
  • Constructor pattern tests
  • Atom feed parsing tests

✅ Integration Tests (12 tests - 11 passing, 1 skipped)

  • Live API tests for basic retrieval
  • Tested with Human Rights Act 1998, Freedom of Information Act 2000
  • Verified XML, Atom feed, and HTML responses
  • Point-in-time version tests
  • Known limitation documented (provision endpoints)

Phase 3: Type Safety with Enums ✅ COMPLETE

Status: All objectives achieved - Production ready

✅ Extension Methods

  • Created LegislationTypeExtensions class
  • ToUriCode() - Convert enum to URI string ("ukpga")
  • FromUriCode() - Convert URI string to enum
  • TryFromUriCode() - Safe conversion with out parameter

✅ Refit Integration

  • Created LegislationTypeUrlParameterFormatter
  • Automatic enum-to-string conversion in URLs
  • Integrated into RefitSettings

✅ API Updates

  • Updated ILegislationApi to use LegislationType enum (9 methods)
  • Updated LegislationApiExtensions to use enums
  • Zero breaking changes to public API surface

✅ Testing

  • Updated all 9 unit tests to use enums
  • Updated all 12 integration tests to use enums
  • Added 5 new tests for extension methods
  • Total: 27 tests (26 passing, 1 skipped)

✅ Documentation

  • README.md completely rewritten with enum examples
  • All 37 legislation types documented
  • Type conversion utilities documented
  • Current status and working features listed

Benefits Delivered:

  • 🔒 Compile-time safety (no string typos possible)
  • 💡 IntelliSense support (all 37 types discoverable)
  • 📖 Self-documenting code
  • 🔄 Bidirectional enum ↔ string conversion

Phase 4: Enhanced XML Parsing ⏳ PLANNED

Goal: Full CLML (Crown Legislation Markup Language) parsing

  1. CLML Parser

    • Parse full XML structure
    • Extract all metadata fields
    • Parse document hierarchy (parts, chapters, sections)
    • Extract provision content with formatting
  2. Models Enhancement

    • Add detailed CLML-specific properties
    • Support for all XML elements
    • Preserve formatting and structure
  3. Tests

    • Unit tests with sample CLML documents
    • Integration tests verifying full parsing

Phase 5: Remaining Phases

  • Point-in-Time & Versions (partially done)
  • Feeds API (done via Atom)
  • Changes & Amendments
  • Effects & Impacts
  • Geographical Extent (model done, parsing needed)
  • Advanced Features
  • Types & Metadata API
  • Resilience & Error Handling (partially done)
  • Documentation & Examples
  • Performance & Optimization
  • NuGet Package & Release

Document Version: 3.0
Last Updated: January 2025
Status: Phase 3 Complete - Type-Safe Enum API Production Ready
Current Progress: 3 of 14 phases complete (21%)
Test Results: 26/27 passing (96% success rate)
Next Steps:

  1. Implement type-safe enum usage ✅ Complete (Phase 3)
  2. Begin Phase 4 - Enhanced CLML XML parsing for full metadata extraction
  3. Implement search API with type-safe filters