REST API Starter

The jhelm-rest module provides a Spring Boot starter that exposes Helm operations as a REST API with OpenAPI/Swagger documentation.

1. Getting Started

1.1. Maven Dependency

Add jhelm-rest to your Spring Boot web application:

<dependency>
    <groupId>org.alexmond</groupId>
    <artifactId>jhelm-rest</artifactId>
    <version>{jhelm-version}</version>
</dependency>

For Swagger UI, add springdoc-openapi:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>3.0.2</version>
</dependency>

1.2. Sample Application

A ready-to-run sample is available in the jhelm-rest-sample module:

cd jhelm-rest-sample
../mvnw spring-boot:run

Open http://localhost:8080/swagger-ui.html to see all endpoints.

2. Configuration

Property Default Description

jhelm.rest.base-path

/api/v1

Base path prefix for all REST endpoints

jhelm.rest.temp-dir

System temp dir

Base directory for server-managed temporary files used during chart operations

jhelm:
  rest:
    base-path: /api/v1
    temp-dir: /var/lib/jhelm/tmp

3. Auto-Configuration

JhelmRestAutoConfiguration conditionally registers controllers based on available beans from JhelmCoreAutoConfiguration:

Controller Condition Endpoints

ReleaseController

ListAction + InstallAction + RepoManager present (requires jhelm-kube)

15 release management endpoints

ChartController

TemplateAction + RepoManager present

9 chart operation endpoints

RepoController

RepoManager present

9 repository management endpoints

HubController

SearchHubAction present

1 ArtifactHub search endpoint

DependencyController

DependencyResolver present

1 dependency management endpoint

Release endpoints require jhelm-kube on the classpath (Kubernetes client). All other endpoints work with jhelm-core alone.

4. API Reference

4.1. Releases — /api/v1/releases

Method Path Description

GET

/releases?namespace=default

List all releases in a namespace

GET

/releases/{name}?namespace=default

Get release status

POST

/releases

Install a release from a chart reference

POST

/releases/upload

Install a release from an uploaded .tgz archive (multipart)

PUT

/releases/{name}?namespace=default

Upgrade a release from a chart reference

POST

/releases/{name}/upgrade/upload?namespace=default

Upgrade a release from an uploaded .tgz archive (multipart)

DELETE

/releases/{name}?namespace=default

Uninstall a release

GET

/releases/{name}/history?namespace=default

Get release revision history

POST

/releases/{name}/rollback?namespace=default

Rollback to a previous revision

POST

/releases/{name}/test?namespace=default&timeoutSeconds=300

Run test hooks

GET

/releases/{name}/values?namespace=default&all=false

Get release values (user overrides or all merged)

GET

/releases/{name}/manifest?namespace=default

Get rendered Kubernetes manifest

GET

/releases/{name}/notes?namespace=default

Get release notes

GET

/releases/{name}/hooks?namespace=default

List Helm hooks

GET

/releases/{name}/resources?namespace=default

List resource statuses

4.1.1. Install a Release

From a chart reference:

curl -X POST http://localhost:8080/api/v1/releases \
  -H 'Content-Type: application/json' \
  -d '{
    "chartRef": "bitnami/nginx",
    "version": "18.3.1",
    "releaseName": "my-release",
    "namespace": "production",
    "values": {
      "replicaCount": 3,
      "image": {"tag": "v2.0"}
    },
    "dryRun": false
  }'

From an uploaded .tgz archive:

curl -X POST http://localhost:8080/api/v1/releases/upload \
  -F 'chart=@nginx-18.3.1.tgz;type=application/gzip' \
  -F 'request={"releaseName": "my-release", "namespace": "production"};type=application/json'

4.1.2. Upgrade a Release

From a chart reference:

curl -X PUT http://localhost:8080/api/v1/releases/my-release?namespace=production \
  -H 'Content-Type: application/json' \
  -d '{
    "chartRef": "bitnami/nginx",
    "version": "19.0.0",
    "values": {"image": {"tag": "v2.1"}},
    "dryRun": false
  }'

From an uploaded .tgz archive:

curl -X POST http://localhost:8080/api/v1/releases/my-release/upgrade/upload?namespace=production \
  -F 'chart=@nginx-19.0.0.tgz;type=application/gzip' \
  -F 'request={"values": {"image": {"tag": "v2.1"}}};type=application/json'

4.1.3. Rollback a Release

curl -X POST http://localhost:8080/api/v1/releases/my-release/rollback?namespace=production \
  -H 'Content-Type: application/json' \
  -d '{"revision": 2}'

4.2. Charts — /api/v1/charts

Method Path Description

POST

/charts/template

Render chart templates from a chart reference

POST

/charts/template/upload

Render chart templates from an uploaded .tgz archive (multipart)

POST

/charts/create

Scaffold a new chart and return as .tgz download

GET

/charts/show?chartRef=…​&version=…​

Show all chart info (metadata, values, README)

GET

/charts/show/values?chartRef=…​&version=…​

Show default values.yaml

GET

/charts/show/readme?chartRef=…​&version=…​

Show chart README

GET

/charts/show/chart?chartRef=…​&version=…​

Show Chart.yaml metadata

GET

/charts/show/crds?chartRef=…​&version=…​

Show Custom Resource Definitions

4.2.1. Render Templates

From a chart reference:

curl -X POST http://localhost:8080/api/v1/charts/template \
  -H 'Content-Type: application/json' \
  -d '{
    "chartRef": "bitnami/nginx",
    "version": "18.3.1",
    "releaseName": "my-release",
    "namespace": "production",
    "values": {"replicaCount": 3}
  }'

From an uploaded .tgz archive:

curl -X POST http://localhost:8080/api/v1/charts/template/upload \
  -F 'chart=@nginx-18.3.1.tgz;type=application/gzip' \
  -F 'request={"releaseName": "my-release", "namespace": "production"};type=application/json'

4.2.2. Create a Chart

curl -X POST http://localhost:8080/api/v1/charts/create \
  -H 'Content-Type: application/json' \
  -o my-chart.tgz \
  -d '{"name": "my-chart"}'

Response: binary .tgz download with Content-Type: application/gzip.

4.3. Repositories — /api/v1/repos

Method Path Description

POST

/repos

Add a chart repository

GET

/repos

List all configured repositories

DELETE

/repos/{name}

Remove a repository

POST

/repos/{name}/update

Update repository index

GET

/repos/{name}/charts

List all charts in a repository

GET

/repos/{name}/charts/{chart}/versions

List available chart versions

POST

/repos/pull

Pull a chart (repo or OCI) and return as .tgz download

POST

/repos/update-all

Update all repository indices

POST

/repos/push

Push an uploaded .tgz chart to a remote registry (multipart)

4.3.1. Add a Repository

curl -X POST http://localhost:8080/api/v1/repos \
  -H 'Content-Type: application/json' \
  -d '{"name": "bitnami", "url": "https://charts.bitnami.com/bitnami"}'

4.3.2. List Charts in a Repository

curl http://localhost:8080/api/v1/repos/bitnami/charts

Response:

[
  {"name": "bitnami/nginx", "chartVersion": "18.3.1", "appVersion": "1.27.3", "description": "..."},
  {"name": "bitnami/redis", "chartVersion": "20.0.0", "appVersion": "7.4.1", "description": "..."}
]

4.3.3. List Chart Versions

curl http://localhost:8080/api/v1/repos/bitnami/charts/nginx/versions

Response:

[
  {"name": "nginx", "chartVersion": "18.3.1", "appVersion": "1.27.3", "description": "..."},
  {"name": "nginx", "chartVersion": "18.3.0", "appVersion": "1.27.3", "description": "..."}
]

4.3.4. Pull a Chart

Pulls from a repository or OCI registry. The endpoint auto-detects OCI URLs by the oci:// prefix.

From a repository:

curl -X POST http://localhost:8080/api/v1/repos/pull \
  -H 'Content-Type: application/json' \
  -o nginx-18.3.1.tgz \
  -d '{"chart": "bitnami/nginx", "version": "18.3.1"}'

From an OCI registry:

curl -X POST http://localhost:8080/api/v1/repos/pull \
  -H 'Content-Type: application/json' \
  -o nginx-1.0.0.tgz \
  -d '{"chart": "oci://registry.example.com/charts/nginx:1.0.0"}'

Response: binary .tgz download with Content-Type: application/gzip.

4.3.5. Update All Repositories

curl -X POST http://localhost:8080/api/v1/repos/update-all

4.3.6. Push a Chart

curl -X POST http://localhost:8080/api/v1/repos/push \
  -F 'chart=@nginx-1.0.0.tgz;type=application/gzip' \
  -F 'remote=oci://registry.example.com/charts/nginx'

4.4. Hub — /api/v1/hub

Method Path Description

GET

/hub/search?keyword=…​&maxResults=20

Search ArtifactHub for Helm charts

4.4.1. Search ArtifactHub

curl 'http://localhost:8080/api/v1/hub/search?keyword=nginx&maxResults=5'

Response:

[
  {
    "name": "nginx",
    "version": "18.3.1",
    "appVersion": "1.27.3",
    "repoName": "bitnami",
    "repoUrl": "https://charts.bitnami.com/bitnami",
    "description": "NGINX Open Source is a web server..."
  }
]
ArtifactHub API limits maxResults to 60 per request.

4.5. Dependencies — /api/v1/dependencies

Method Path Description

POST

/dependencies/resolve

Resolve dependency versions from a chart reference and return Chart.lock YAML

4.5.1. Resolve Dependencies

curl -X POST http://localhost:8080/api/v1/dependencies/resolve \
  -H 'Content-Type: application/json' \
  -d '{"chartRef": "bitnami/nginx", "version": "18.3.1"}'

Response: YAML content with Content-Type: text/yaml:

dependencies:
- name: redis
  version: "18.0.0"
  repository: "https://charts.bitnami.com/bitnami"
digest: "sha256:..."
generated: "2026-03-08T..."

5. Error Handling

All endpoints return consistent error responses via JhelmRestExceptionHandler:

  • 400 Bad Request — Missing required fields or invalid arguments

  • 404 Not Found — Release or resource not found

Error response format:

{"message": "chartRef is required"}

6. Spring Boot Integration

6.1. Minimal Application

@SpringBootApplication
public class MyHelmApp {
    public static void main(String[] args) {
        SpringApplication.run(MyHelmApp.class, args);
    }
}

With jhelm-rest on the classpath, all endpoints are auto-configured. No additional code is needed.

6.2. Custom Base Path

jhelm:
  rest:
    base-path: /helm/api

All endpoints will be available under /helm/api/releases, /helm/api/charts, etc.

6.3. Overriding Controllers

All controllers are registered with @ConditionalOnMissingBean. Define your own to replace:

@RestController
@RequestMapping("/api/v1/releases")
public class CustomReleaseController {
    // Your custom implementation
}