Parsing WADL – From Specification to Opportunity

From PiRho Knowledgebase
Jump to navigationJump to search

Summary: This article explores the practical journey of turning WADL from a static XML document into a fully executable API contract. It covers DOM parsing, XPointer limitations, method dereferencing, parameter inheritance, multi-pass processing, and the surprising architectural opportunities unlocked once WADL becomes machine‑actionable.

What WADL Actually Is

WADL (Web Application Description Language) is an XML-based format for describing RESTful HTTP services. A WADL document typically defines:

  • <resources> and nested <resource> elements
  • <method> definitions
  • <request> and <response> blocks
  • <param> definitions (template, matrix, query, header, plain)
  • <representation> types
  • Resource types and method references (via @type and @href)

Although WADL never reached mainstream popularity, it remains one of the most structured and precise ways to describe RESTful endpoints. Once parsed semantically, it becomes a highly expressive API contract.

Why Parsing WADL Is Surprisingly Hard

WADL appears simple at first glance, but real-world documents introduce deep structural complexity:

  • Resources can be deeply nested
  • Parameters inherit differently depending on style
  • Methods may reference other methods using @href
  • Resource types can inject methods into resources
  • Representations may include <doc>, <param> or even nested <representation>
  • Faults (error responses) must be merged like any other response
  • External fragments may be included

These are not edge cases—they are core WADL features. Handling them correctly requires a full structural model, not just XML parsing.

XPointer vs DOM: The Early Realisation

Where XPointer Helps

XPointer gives precise, declarative mappings such as resource/wadl:param[@style="matrix"]. It is excellent at:

  • Defining mappings
  • Providing documentation clarity
  • Addressing nodes symbolically
  • Spec-level modelling

Where XPointer Fails

XPointer is not a processing model. It cannot:

  • Walk parents, children, or siblings
  • Merge inherited context
  • Split or combine path segments
  • Build a router or a tree
  • Resolve includes or fragments
  • Perform multipass analysis

It tells you ‘‘what’’ to pick, but never ‘‘how’’ to process it. This is where DOM becomes essential.

Why DOM Became the Backbone

Parsing WADL as a DOM unlocks:

  • True hierarchical navigation (parents/children/siblings)
  • Path building ("/Users/{id}") from nested <resource> nodes
  • Parameter inheritance by walking upward
  • Resource-type merging
  • Multi-pass processing
  • Safe inclusion of external documents
  • Accurate debugging with file/line provenance

DOM is mandatory for constructing an accurate execution model. Every mature WADL implementation uses this pattern.

Designing a Real Parser: A Multi‑Pass Architecture

The journey revealed that WADL requires a multi-stage processing pipeline.

Pass 1 — Parse WADL → DOM

  • Namespace-aware parsing (use localName, not tagName)
  • Capture every node: resources, methods, params, faults, representations
  • Resolve <include> fragments
  • Build the raw tree structure faithfully

Pass 2 — Build the Method Registry

  • Collect every <method> with an @id
  • Registry works across application, resource_type, and resource scopes
  • Provides canonical method definitions for dereferencing
  • Handles duplicates, cycles, and external references defensively

Pass 3 — Dereference @href (Method Linking)

Many WADL documents use: #globalGetJson

Dereferencing performs:

  • Lookup → clone canonical method
  • Merge → overlay local attributes (locals win)
  • Recursion → resolve chained references (#A → #B → #C)
  • Cycle detection
  • Remove @href
  • Add provenance (_resolvedFrom)

After this pass, all methods are fully materialised.

Pass 4 — Parameter Inheritance

Only resource-level params inherit. Method/request/representation params remain local.

Two inheritance domains:

Path-bound
template, matrix
Context-bound
query, header

Rules:

  • Inheritance flows top‑down
  • Local definitions override inherited ones (by style:name)
  • Required flags propagate unless locally overridden
  • Resource-type params merge into the chain
  • Effective params are stamped onto each resource and method


Pass 5 — Normalisation & Stable Output

  • De-duplicate
  • Sort keys for deterministic builds
  • Strip debug fields when not in debug mode
  • Validate no unresolved @href remain
  • Validate no cycles or missing refs
  • Finalise effective parameter sets


Pass 6 — Emit the Router Model

Once fully resolved, the WADL becomes a runtime construct:

  • A Route Register (flat list of routes)
  • A Trie (for high-speed matching)
  • Complete produces[] and consumes[] lists
  • Required parameter indexes
  • Handler binding metadata


This transforms WADL from “XML config” into “router-ready instruction set”.

Unexpected Lessons Learned

Several insights emerged:

  • XPointer is for modelling, not execution.
  • Resource-type inheritance can create multi-layer method injection.
  • Dereferencing must occur before inheritance.
  • Only resource-level params inherit; others never bubble up.
  • Some WADLs use <link> or nested <representation>, requiring flexible parsing.
  • Faults must be merged predictably with standard responses.
  • Deterministic output is vital for debugging and CI.


A Fully-Featured Test WADL

Our comprehensive WADL example included:

  • Global methods (HTML/JSON GET, JSON POST)
  • Resource types (htmlView, jsonView, editableCollection)
  • Nested resources (Items → {ItemID} → Versions → {VersionID})
  • Parameter overrides at every level
  • Request/response bodies and media types
  • Fault definitions
  • Link elements
  • External @href stub

This allowed testing every major WADL feature end‑to‑end.

What You Gain Once WADL Becomes Executable

1. A Complete Machine‑Readable Contract

WADL becomes a canonical, unambiguous API description with:

  • No missing methods
  • No unresolved references
  • No ambiguity in inheritance or defaults
  • All parameters and types fully resolved

2. Automatic Router Generation

The resolved model directly produces:

  • Path patterns
  • Trie nodes
  • Required parameters
  • Media-type negotiation rules
  • Handler binding metadata

3. API Introspection & Documentation

Once WADL is executable, you can automatically derive:

  • Human-readable API documentation
  • Capability discovery
  • Linting and contract validation
  • Regression tests
  • Contract drift detection

4. Multi‑Format Output

From the resolved tree, it becomes trivial to generate:

  • OpenAPI
  • RAML
  • GraphQL schemas
  • SDKs
  • Client libraries
  • Server stubs
  • Static documentation sites

5. Component-Level Integration

In a Component/Neurone ecosystem:

  • Each component declares a WADL
  • The system integrates capabilities automatically
  • Routing, validation, and schema handling emerge organically

Final Thoughts

WADL is often overlooked, but when paired with:

  • A DOM parser
  • Multi-pass processing
  • Dereferencing
  • Inheritance resolution
  • A stable, deterministic output model

…it becomes a powerful and expressive API definition language. This approach yields an API contract that is precise, introspectable, automatable, and deeply compatible with modern component-based architectures.