hclapi

package module
v0.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 8, 2026 License: MIT Imports: 3 Imported by: 0

README

[!IMPORTANT] hclapi is in early development (v0.1.x) and follows documentation-driven development. Some documented features haven't been implemented yet. Bugs and breaking changes are to be expected. Feedback and issue reports are welcome.

hclapi

Go Reference Release CI

hclapi is a declarative backend runtime distributed as a single lightweight static binary. It compiles HashiCorp Configuration Language (HCL) manifests, SQL queries, and sandboxed Starlark scripts into structured HTTP services with native connection pooling, schema validation, and automatic OpenAPI 3.1 documentation.

Manifests are parsed and validated at boot time and executed directly at runtime. hclapi doesn't generate or compile Go code.

Documentation · Quickstart · Why hclapi · Patterns · Examples

Supported connectors

hclapi connects natively to databases and storage layers using zero-CGO pure Go drivers:

Category Driver Supported engines Status
Relational SQL "postgres" PostgreSQL, Supabase, TimescaleDB, AWS Aurora Available
"sqlite" SQLite3, Turso, LibSQL Available
"mysql" MySQL, MariaDB, PlanetScale, TiDB Available
"sqlserver" Microsoft SQL Server, Azure SQL Available
"oracle" Oracle Database 11g – 23ai Available
"cockroachdb" CockroachDB Dedicated & Serverless Available
Analytical SQL "clickhouse" ClickHouse Cloud & Self-Hosted Available
"duckdb" DuckDB Embedded Columnar Available
Key-Value / Cache "redis" Redis, Valkey, AWS ElastiCache In-progress

Example

A production user registration endpoint with input normalization, parameterized SQL insertion, constraint collision interception, and structured RFC 9457 error responses:

server {
  host          = "0.0.0.0"
  port          = 8080
  max_body_size = "5MB"
}

connection "postgres" "main" {
  source = env("DATABASE_URL")

  pool {
    max_open     = 25
    max_lifetime = "30m"
  }
}

schema "user_create" {
  field "email" {
    type        = string
    required    = true
    format      = "email"
    description = "Primary user login and notification email"
  }

  field "full_name" {
    type       = string
    required   = true
    min_length = 2
    max_length = 100
  }

  field "role" {
    type    = string
    default = "member"
    enum    = ["admin", "member", "viewer"]
  }
}

endpoint "POST /api/v1/users" {
  description = "Registers a new user account and provisions a default workspace."

  request {
    body = schema.user_create
  }

  pipeline {
    # 1. Sandboxed data transformation
    starlark "normalize" {
      source = <<-STARLARK
        def execute(ctx):
          email = ctx.request.body.get("email", "").strip().lower()
          name = ctx.request.body.get("full_name", "").strip()
          return {
            "email": email,
            "name": name,
            "handle": email.split("@")[0]
          }
      STARLARK
    }

    # 2. Parameterized SQL insert with constraint interception
    sql "insert_user" {
      connection = connection.postgres.main
      query      = <<-SQL
        INSERT INTO users (email, name, role)
        VALUES (@email, @name, @role)
        RETURNING id, email, name, role, created_at
      SQL
      args = {
        email = steps.normalize.result.email
        name  = steps.normalize.result.name
        role  = ctx.request.body.role
      }

      # Intercept PostgreSQL unique violation (code 23505)
      catch "23505" {
        status  = 409
        headers = {
          "X-Error" = "Conflict"
        }
        body    = problem(409, "A user with this email address already exists", "email-collision")
      }
    }

    # 3. Terminal 201 response with created record
    respond {
      status  = 201
      headers = {
        "Location" = "/api/v1/users/${steps.insert_user.row.id}"
      }
      body    = steps.insert_user.row
    }
  }
}

Quick install

Linux and macOS
curl -fsSL https://raw.githubusercontent.com/ju4n97/hclapi/main/scripts/install.sh | bash
Windows (PowerShell)
irm https://raw.githubusercontent.com/ju4n97/hclapi/main/scripts/install.ps1 | iex
Container (Docker / Podman)
docker run --rm -p 8080:8080 -v "$(pwd):/app:ro" ghcr.io/ju4n97/hclapi:latest serve -c /app
Using Go
go install github.com/ju4n97/hclapi/cmd/hclapi@latest

(Linux .deb, .rpm, .apk, and .pkg.tar.zst packages are available on the releases page).

See the Installation guide for package manager setup and verification.

Embedding in Go

hclapi.Engine implements standard http.Handler and mounts directly into any Go HTTP router:

package main

import (
  "log/slog"
  "net/http"
  "os"

  "github.com/ju4n97/hclapi"
)

func main() {
  logger := slog.New(slog.NewTextHandler(os.Stdout, nil))

  engine, err := hclapi.New(hclapi.Options{
    ConfigPath:   "./api",
    StrictTyping: true,
    Logger:       logger,
  })
  if err != nil {
    logger.Error("engine initialization failed", "error", err)
    os.Exit(1)
  }
  defer engine.Close()

  mux := http.NewServeMux()
  mux.HandleFunc("GET /healthz", func(w http.ResponseWriter, r *http.Request) {
  w.WriteHeader(http.StatusOK)
    _, _ = w.Write([]byte("OK"))
  })
  mux.Handle("/", engine.Handler())

  logger.Info("server listening on :8080")
  _ = http.ListenAndServe(":8080", mux)
}

See Go integration for custom error handlers, logging, and registering native Go steps.

Documentation

Full reference documentation covering the request lifecycle, manifest block syntax, and patterns is available at: ju4n97.github.io/hclapi

Contributing

See CONTRIBUTING.md for architectural guidelines, repository structure, and development workflows.

License

MIT

Documentation

Overview

Package hclapi provides a declarative, embeddable API runtime engine.

Index

Constants

This section is empty.

Variables

View Source
var DefaultProblemHandler = problem.DefaultHandler

DefaultProblemHandler formats and serializes errors as application/problem+json.

Functions

This section is empty.

Types

type Args added in v0.1.2

type Args = runtime.Args

Args represents evaluated arguments passed to a Go step callback.

type Engine

type Engine = engine.Engine

Engine coordinates manifest execution, connection pools, and HTTP routing.

func New added in v0.1.3

func New(options Options) (*Engine, error)

New compiles manifests and initializes the HTTP engine.

type ExecutionContext added in v0.1.2

type ExecutionContext = runtime.ExecutionContext

ExecutionContext encapsulates the state for a single HTTP pipeline run.

type InvalidParam

type InvalidParam = problem.InvalidParam

InvalidParam captures a single field validation constraint failure.

type Options

type Options = engine.Options

Options defines configuration parameters for initializing an Engine.

type Problem added in v0.1.2

type Problem = problem.Problem

Problem represents an RFC 9457 compliant error object.

func NewProblem added in v0.1.2

func NewProblem(status int, detail ...string) Problem

NewProblem constructs a Problem with canonical title and type derived from the status code.

type ProblemHandler added in v0.1.2

type ProblemHandler = problem.Handler

ProblemHandler defines the contract for serializing Problem Details to an HTTP client.

type RequestState

type RequestState = runtime.RequestState

RequestState holds normalized, read-only HTTP request metadata.

type Step added in v0.1.2

type Step = runtime.Step

Step provides invocation arguments and request context to a Go step callback.

type StepHandler

type StepHandler = runtime.StepHandler

StepHandler defines the signature for custom native Go step callbacks.

Directories

Path Synopsis
cmd
hclapi command
examples
05_go_embedded command
internal
eval
Package eval translates runtime core.Context data into HCL EvalContext structures and dynamically evaluates HCL AST expressions back into Go primitives.
Package eval translates runtime core.Context data into HCL EvalContext structures and dynamically evaluates HCL AST expressions back into Go primitives.
runtime
Package runtime manages request-scoped execution state, step outputs, and context lifecycles for pipeline runs.
Package runtime manages request-scoped execution state, step outputs, and context lifecycles for pipeline runs.
validator
Package validator enforces schema types, format constraints, and default value normalization.
Package validator enforces schema types, format constraints, and default value normalization.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL