Jenkins REST API Architecture: How Endpoints Are Exposed via Stapler
Jenkins exposes its REST API through the Stapler web framework using the hudson.model.Api class, which dispatches URLs ending in /api/* to format-specific methods that serialize annotated model objects into XML, JSON, or Python literals.
The Jenkins REST API architecture provides programmatic access to virtually every first-class entity in the automation server. Built on top of the Stapler web framework, this architecture allows any model object extending AbstractModelObject to expose data via standardized HTTP endpoints. Understanding how the Api class processes requests reveals the mechanism behind the consistent /api/ URL patterns found throughout the jenkinsci/jenkins codebase.
Stapler Framework and the Api Class
Jenkins implements its remote API on top of the Stapler web framework. Every model object that needs to be reachable via HTTP can expose an Api helper object, specifically the class hudson.model.Api. When a request hits a URL ending with /api/…, Stapler creates an instance of Api for the target object and dispatches to one of its do* methods based on the suffix.
The mapping follows this pattern:
…/api/xml→Api.doXmlreturns the bean as XML…/api/json→Api.doJsonreturns the bean as JSON (or JSONP when thejsonpquery param is present)…/api/python→Api.doPythonreturns the bean as a Python literal
Additional parameters allow selective field selection, depth control, XPath filtering, and wrapper element naming for any URL pattern under /api/*.
Request Processing Pipeline in Api.java
The core implementation lives in core/src/main/java/hudson/model/Api.java. The pipeline follows a strict sequence from security checks through serialization.
Security Headers and Permission Checks
Every API response begins with header preparation. The setHeaders() method adds security-oriented response headers including X‑Jenkins, X‑Content‑Type‑Options, and X‑Frame‑Options to the response (lines 307-315 in Api.java).
Before exposing primitive XPath results or JSONP, the permit() method consults all registered SecureRequester extensions. These plugins enforce CSRF protection and other security policies, located at lines 298-304 in the same file.
Model Building with Exported Annotations
The ModelBuilder class inspects the target class’s @Exported and @ExportedBean annotations to build a Model describing the fields that can be serialized. This occurs at lines 62-64 in Api.java. Model classes throughout the codebase—such as jenkins/model/Jenkins.java (lines 354-356), hudson/model/Run.java, and hudson/model/Computer.java—use these annotations to define their API surface.
Tree Pruning for Selective Data Retrieval
To prevent massive object graphs from being serialized, the architecture employs TreePruner implementations. Either a depth-based ByDepth or a path-based NamedPathPruner limits which parts of the object graph are emitted. This allows callers to request only the needed subtree via the tree or depth query parameters (lines 222-224 in Api.java).
Serialization and Format Selection
Depending on the requested format, the bean is handed to StaplerResponse.serveExposedBean with the appropriate Flavor enum value (XML, JSON, JSONP, or PYTHON). This occurs at lines 58-60 in Api.java, with the flavor definitions typically found near lines 15-17.
XPath Processing and XML Filtering
For XML output specifically, the API supports server-side XPath processing. When the xpath query parameter is present, the implementation parses the generated XML into a DOM, runs the XPath expression, and removes any exclude nodes before writing the final output (lines 26-44 and 45-73 in Api.java). The optional wrapper parameter allows wrapping the XPath result in a custom element name, useful for maintaining valid XML structure when extracting single values.
Practical API Usage Examples
Because any object implementing AbstractModelObject exposes this interface, you can query Jenkins entities directly:
# Get the whole Jenkins instance as XML
curl -s https://jenkins.example.com/api/xml
# Get only the list of jobs (name & color) as JSON
curl -s https://jenkins.example.com/api/json?tree=jobs[name,color]
# Fetch a specific build as a Python literal
curl -s https://jenkins.example.com/job/example/42/api/python
# Use XPath to retrieve just the <fullName> of a job (XML)
curl -s "https://jenkins.example.com/job/example/api/xml?xpath=//fullName"
# Wrap the XPath result in a custom element called <info>
curl -s "https://jenkins.example.com/job/example/api/xml?xpath=//fullName&wrapper=info"
# JSONP (requires a SecureRequester implementation to permit it)
curl -s "https://jenkins.example.com/api/json?jsonp=callback"
Summary
- Jenkins REST API architecture relies on Stapler's dispatch mechanism to route
/api/*requests to thehudson.model.Apiclass. - The core implementation in
/core/src/main/java/hudson/model/Api.javahandles XML, JSON, JSONP, and Python output formats through dedicateddo*methods. - Security is enforced via
SecureRequesterextensions and hardened response headers set bysetHeaders(). @Exportedand@ExportedBeanannotations drive theModelBuilderto determine which fields are serializable across model classes likeJenkins,Job, andRun.- Tree pruning via
TreePrunerimplementations (such asNamedPathPruner) allows selective field retrieval using thetreeordepthparameters. - Optional XPath processing enables server-side filtering of XML responses with support for custom wrapper elements.
Frequently Asked Questions
What framework does Jenkins use for its REST API?
Jenkins uses the Stapler web framework. According to the jenkinsci/jenkins source code, the Api class acts as a dispatcher that Stapler invokes when URLs end with /api/..., routing requests to methods like doXml or doJson based on the specific path suffix.
How does Jenkins determine which fields to expose in API responses?
The ModelBuilder class scans for @Exported and @ExportedBean annotations on model classes. As implemented in core/src/main/java/hudson/model/Api.java (lines 62-64), this builder constructs a Model that describes the fields eligible for serialization, driving the output for classes like Jenkins, Job, and Run.
Can I filter the API response to include only specific fields?
Yes. Use the tree query parameter with a path expression such as jobs[name,color] or the depth parameter to limit object graph traversal. The TreePruner—specifically NamedPathPruner or ByDepth—processes these parameters in Api.java (lines 222-224) to reduce payload size and improve performance.
What security mechanisms protect the Jenkins REST API?
The Api class invokes setHeaders() to add security headers like X-Content-Type-Options and X-Frame-Options to every response (lines 307-315 in Api.java). Additionally, the permit() method checks all registered SecureRequester extensions before allowing JSONP or primitive XPath results, preventing CSRF attacks and unauthorized data access.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →