Documentation
¶
Overview ¶
Package ngrokgin serves a Gin router through an ngrok endpoint with one call.
ngrok-go's ngrok.EndpointListener is a real net.Listener, and Gin's gin.Engine.RunListener already accepts one directly — so unlike the Axum and FastAPI siblings, there's no separate upstream port or manual connection-serving loop to write. Confirmed live: WithPoolingEnabled, WithBindings, WithTrafficPolicy, and WithURL all exist on ngrok-go v2 with parity to the other SDKs, and router.RunListener(ln) round-trips a real request through the public ngrok URL.
package main
import (
"context"
"github.com/gin-gonic/gin"
ngrokgin "github.com/ngrok-samples/ngrok-gin"
)
func main() {
router := gin.Default()
router.GET("/", func(c *gin.Context) { c.String(200, "hello") })
ngrokgin.Serve(context.Background(), router, ngrokgin.Config{})
}
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Serve ¶
Serve opens a single ngrok endpoint per config and serves router on it. Shorthand for the one-endpoint case of ServeMany. Blocks until the listener closes or a connection-level error occurs.
Types ¶
type Binding ¶
type Binding string
Binding is the endpoint's ingress binding. Not part of ngrok's Traffic Policy — confirmed by checking the Traffic Policy actions reference directly, so this stays a standalone field rather than folded into TrafficPolicy.
type CollisionError ¶
CollisionError is returned by Serve or ServeMany, before any ngrok session is opened, when two or more configs would silently collide on the same URL without pooling enabled.
ngrok does not reject or warn when two listeners in the same session end up on the same public url — it silently lets the most recently opened listener win, and the other becomes unreachable with zero indication of why. Confirmed live against the real SDK, isolated from this package's own code (a standalone program opening two listeners with no domain, no pooling, saw both succeed with the identical URL, no error either time). A config with no explicit URL falls back to the account's default dev domain, so two URL-less configs collide there just as surely as two hardcoding the same string.
Note this is a different failure mode than a cross-session claim on a domain (another running agent, or a dashboard-configured Cloud Endpoint) — ngrok rejects that loudly on its own (ERR_NGROK_334), confirmed live; this guard only covers the silent same-session case ngrok doesn't catch.
func (*CollisionError) Error ¶
func (e *CollisionError) Error() string
type Config ¶
type Config struct {
// URL is the reserved domain for this endpoint. Empty falls back to the
// account's default dev domain.
URL string
// Pooling opts in to ngrok endpoint pooling — required if another
// endpoint on the same session would otherwise land on the same domain.
// ngrok does not reject or warn on that collision by default: confirmed
// live against the real SDK that two listeners opened with no domain and
// no pooling both succeed silently, returning the identical URL, with
// only the most recently opened one actually receiving traffic.
Pooling bool
// TrafficPolicy is a raw ngrok Traffic Policy document (YAML or JSON),
// passed straight through. See https://ngrok.com/docs/traffic-policy/.
TrafficPolicy string
Binding Binding
}
Config configures a single ngrok endpoint.
Deliberately minimal, same reasoning as the ngrok-axum and ngrok-fastapi siblings: the many granular per-module options ngrok's SDKs used to offer (basic auth, oauth, header manipulation, CIDR restrictions, etc.) mirror ngrok's old "Edge Modules" system, superseded by Traffic Policy — use TrafficPolicy for all of that instead.