archview

Frameworks

Route extraction per framework, and how to add your own.

Each framework registers routes differently, so endpoint detection is delegated to per-framework extractors. The built-ins are net/http, gin, echo, gRPC, GraphQL and ConnectRPC; each runs automatically (an extractor only fires on a package that uses its framework).

net/http

Detects mux.HandleFunc(pattern, handler) on *http.ServeMux and the package-level http.HandleFunc. The Go 1.22+ method-prefixed pattern is parsed:

mux.HandleFunc("GET /catalog/items", h.ListItems)   // method GET, path /catalog/items

gin

Detects GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS, Handle, and Any on *gin.Engine / *gin.RouterGroup:

r := gin.Default()
api := r.Group("/api")
api.GET("/users", userCtl.List)   // handler resolves to (*UserController).List

echo

Detects GET/POST/... and Any on *echo.Echo / *echo.Group. The handler is the argument right after the path; Group("/api") prefixes are joined onto the route. Works with echo v3 and v4.

e := echo.New()
api := e.Group("/api")
api.GET("/users", userCtl.List)   // endpoint /api/users

GraphQL

Detects gqlgen-style resolvers: an interface named Query/Mutation/SubscriptionResolver implemented by a project type. Each field becomes an endpoint bound to the resolver method.

type QueryResolver interface {
    Order(ctx context.Context, id string) (*Order, error)   // endpoint /Query/order
}

Structural detection — no import required, so it works with real gqlgen output. Only root resolvers for now; nested field resolvers are on the roadmap.

gRPC

Detected structurally from the generated registration call — no import needed, so it works with real google.golang.org/grpc as-is. Each RPC method on the service interface becomes an endpoint bound to the implementing method:

pb.RegisterOrderServiceServer(grpcServer, &OrderServer{...})
// endpoints: /OrderService/CreateOrder, /OrderService/GetOrder, ...

The server impl lives in a package classified as controller (e.g. adapter/grpc), so the RPCs flow into your service and repository like any other entry point.

ConnectRPC

Detects the generated New<Svc>Handler(impl) constructor (returns (string, http.Handler)) from connectrpc.com/connect. Each RPC method on the service handler interface becomes an endpoint — so a Connect service shows up even though it doesn't use grpc-go's Register…Server.

Adding a framework

Implement the Extractor interface and pass it via Options.Extractors:

type Extractor interface {
	Name() string
	Match(pkg *packages.Package) bool       // does this pkg import the framework?
	Extract(pkg *packages.Package) []Route  // walk syntax, return routes
}
av, _ := archview.New(archview.Options{
	Extractors: []archview.Extractor{myEchoExtractor{}, /* + defaults */},
})

echo, fiber, chi, GraphQL and WebSocket adapters are on the roadmap. The interface is already in place — contributions welcome.

On this page