hclapi

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Sep 4, 2026 License: MIT Imports: 5 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" {
  url = env("DATABASE_URL")

  pool {
    max_open_conns    = 25
    conn_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.NewEngine(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 serializes Problem 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 from an HCL manifest.

type ByteSize

type ByteSize = scalar.ByteSize

ByteSize represents a quantity of bytes unmarshaled from text (e.g. "25MB", "10GiB").

type Connection added in v0.1.2

type Connection = manifest.Connection

Connection represents a resolved database, cache, or storage backend configuration.

type Duration

type Duration = scalar.Duration

Duration wraps a time.Duration with human-readable text deserialization (e.g. "15m", "30s").

type Engine

type Engine = engine.Engine

Engine is the root coordinator managing manifests, step registries, and HTTP routing.

func NewEngine

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

NewEngine parses manifests, statically verifies routes, and initializes the HTTP engine.

type ExecutionContext added in v0.1.2

type ExecutionContext = runtime.ExecutionContext

ExecutionContext encapsulates the runtime state for a single HTTP request pipeline execution.

type ExecutionContextOption added in v0.1.2

type ExecutionContextOption = runtime.ExecutionContextOption

ExecutionContextOption configures optional behavior during ExecutionContext creation.

type Field added in v0.1.2

type Field = manifest.Field

Field represents a compiled, type-safe schema field constraint rule.

type InvalidParam

type InvalidParam = problem.InvalidParam

InvalidParam represents a single field-level schema validation constraint failure.

type Options

type Options = manifest.Options

Options defines configuration parameters for the hclapi engine.

type PoolConfig added in v0.1.2

type PoolConfig = manifest.PoolConfig

PoolConfig defines connection pool sizing and lifecycle settings.

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 creates a Problem with title and type derived from the HTTP status code.

type ProblemHandler added in v0.1.2

type ProblemHandler = problem.Handler

ProblemHandler defines the contract for custom error serialization.

type RequestState

type RequestState = runtime.RequestState

RequestState represents normalized HTTP request metadata extracted at runtime.

type Schema added in v0.1.2

type Schema = manifest.Schema

Schema represents a compiled, named validation schema.

type Server

type Server = manifest.Server

Server defines the resolved HTTP server transport configuration.

type Step added in v0.1.2

type Step = runtime.Step

Step encapsulates the invocation state, arguments, and request metadata for a Go step.

type StepHandler

type StepHandler = runtime.StepHandler

StepHandler defines the signature for custom native Go step callbacks.

type StepResult

type StepResult = runtime.StepResult

StepResult represents arbitrary step-specific outputs.

Directories

Path Synopsis
cmd
hclapi command
examples
05_go_embedded command
internal
engine
Package engine provides route binding, HTTP multiplexing, and pipeline initialization.
Package engine provides route binding, HTTP multiplexing, and pipeline initialization.
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.
steps/xrespond
Package xrespond serializes payloads and writes final HTTP headers and status codes.
Package xrespond serializes payloads and writes final HTTP headers and status codes.
validator
Package validator enforces OpenAPI 3.1 schema types, format constraints, and default value normalization.
Package validator enforces OpenAPI 3.1 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