apigate 0.2.5

Macro-driven API gateway for Rust — declarative routing, request transformation, and reverse proxying built on axum
Documentation
{
	log {
		level INFO
	}
}

:8081 {
	@ping {
		method GET
		path /ping
	}
	handle @ping {
		respond "pong\n" 200
	}

	@internal {
		method GET
		path /internal
	}
	handle @internal {
		templates
		respond `{
  "kind": "internal",
  "uri": "{{.Req.URL}}",
  "headers": {{.Req.Header | toJson}}
}` 200
	}

	@admin_stats {
		method GET
		path /admin/stats
	}
	handle @admin_stats {
		templates
		respond `{
  "kind": "admin_stats",
  "uri": "{{.Req.URL}}",
  "headers": {{.Req.Header | toJson}}
}` 200
	}

	@user {
		method GET
		path /user
	}
	handle @user {
		templates
		respond `{
  "kind": "user",
  "uri": "{{.Req.URL}}",
  "headers": {{.Req.Header | toJson}}
}` 200
	}

	@secure_user {
		method GET
		path /secure-user
	}
	handle @secure_user {
		templates
		respond `{
  "kind": "secure_user",
  "uri": "{{.Req.URL}}",
  "headers": {{.Req.Header | toJson}}
}` 200
	}

	@products {
		method GET
		path /products
	}
	handle @products {
		templates
		respond `{
  "kind": "products",
  "uri": "{{.Req.URL}}",
  "query": "{{.Req.URL.RawQuery}}",
  "headers": {{.Req.Header | toJson}}
}` 200
	}

	@buy {
		method POST
		path /buy
	}
	handle @buy {
		respond <<EOF
kind=buy
content_type={header.Content-Type}
x_user_id={header.X-User-Id}
body={http.request.body}
EOF 200
	}

	@legacy_create {
		method POST
		path /legacy-create
	}
	handle @legacy_create {
		respond <<EOF
kind=legacy_create
content_type={header.Content-Type}
body={http.request.body}
EOF 200
	}

	@reviews {
		method GET
		path_regexp reviews ^/api/v2/reviews/([^/]+)$
	}
	handle @reviews {
		templates
		respond `{
  "kind": "review",
  "id": "{re.reviews.1}",
  "uri": "{{.Req.URL}}"
}` 200
	}

	@anything {
		method GET
		path /anything
	}
	handle @anything {
		respond "anything-ok\n" 200
	}

	@upload {
		method POST PUT
		path /upload /upload-public
	}
	handle @upload {
		respond "" 204
	}

	@fast {
		method GET
		path /fast
	}
	handle @fast {
		templates
		respond `{
  "kind": "fast",
  "headers": {{.Req.Header | toJson}}
}` 200
	}

	@optimized {
		method GET
		path /optimized
	}
	handle @optimized {
		templates
		respond `{
  "kind": "optimized",
  "headers": {{.Req.Header | toJson}}
}` 200
	}

	@update_by_id {
		method POST
		path_regexp update ^/([^/]+)/update$
	}
	handle @update_by_id {
		respond <<EOF
kind=update
id={re.update.1}
content_type={header.Content-Type}
x_user_id={header.X-User-Id}
body={http.request.body}
EOF 200
	}

	@byid {
		method GET
		path_regexp byid ^/([^/]+)$
		not path /ping /internal /admin/stats /user /secure-user /products /buy /legacy-create /anything /upload /upload-public /fast /optimized
	}
	handle @byid {
		templates
		respond `{
  "kind": "by_id",
  "id": "{re.byid.1}",
  "uri": "{{.Req.URL}}",
  "x_sale_id": "{{.Req.Header.Get "X-Sale-Id"}}",
  "x_apigate_demo": "{{.Req.Header.Get "X-Apigate-Demo"}}",
  "headers": {{.Req.Header | toJson}}
}` 200
	}

	handle {
		respond "not-found\n" 404
	}
}