dixhttp

package
v2.0.0-beta.17 Latest Latest
Warning

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

Go to latest
Published: Feb 26, 2026 License: MIT Imports: 9 Imported by: 1

README ΒΆ

Dix HTTP Visualization Module

This module provides an HTTP server to visualize dependency relationships in the Dix dependency injection container. Designed for large projects, with support for fuzzy search, package grouping, bidirectional dependency tracking, and depth control.

δΈ­ζ–‡ζ–‡ζ‘£

Features

  • πŸ“Š Interactive Visualization - Modern UI built with vis.js + Tailwind CSS + Alpine.js
  • πŸ” Global Fuzzy Search - Quickly search for type names or function names to view dependencies
  • πŸ“¦ Package Grouping - Collapsible left panel to browse by package
  • πŸ”„ Bidirectional Dependency Tracking - Show both upstream (dependencies) and downstream (dependents)
  • πŸ“ Depth Control - Limit dependency graph display levels (1-5 or all)
  • 🎨 Multiple Layouts - Support hierarchical and force-directed layouts
  • 🧩 Group Rules (Prefix Aggregation) - Aggregate nodes by package/prefix rules
  • πŸ”Ž Prefix Filter - Show only nodes/providers matching a prefix
  • 🧭 Group Subgraph - View a group's internal + upstream/downstream dependencies
  • πŸ“‘ RESTful API - Provide JSON format dependency data

Quick Start

package main

import (
    "log"
    "github.com/pubgo/dix/v2"
    "github.com/pubgo/dix/v2/dixhttp"
    "github.com/pubgo/dix/v2/dixinternal"
)

func main() {
    // Create Dix container
    di := dix.New()
    
    // Register providers
    dix.Provide(di, func() *Config {
        return &Config{}
    })
    
    dix.Provide(di, func(c *Config) *Database {
        return &Database{Config: c}
    })
    
    dix.Provide(di, func(db *Database) *UserService {
        return &UserService{DB: db}
    })
    
    // Create and start HTTP server
    server := dixhttp.NewServer((*dixinternal.Dix)(di))
    log.Println("Server starting at http://localhost:8080")
    if err := server.ListenAndServe(":8080"); err != nil {
        log.Fatal(err)
    }
}

Open browser and visit http://localhost:8080 to view the dependency graph.

Base Path / Prefix

If you need to mount the UI and API under a path prefix (e.g. behind a gateway), use WithBasePath:

server := dixhttp.NewServerWithOptions(
  (*dixinternal.Dix)(di),
  dixhttp.WithBasePath("/dix"),
)
// Visit http://localhost:8080/dix/

UI Layout

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  πŸ”— Dix Dependency Visualization            πŸ“¦ 8 Pkgs  ⚑ 42 Provs  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ πŸ“¦ Pkgs  β”‚  [Providers] [Types]  Layout: Hier  Depth: 2  πŸ” Search  β”‚ πŸ“‹ Details  β”‚
β”‚          β”‚                                            β”‚             β”‚
β”‚ πŸ“ All   β”‚                                            β”‚  Function   β”‚
β”‚  42      β”‚           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”                      β”‚  xxx.func   β”‚
β”‚          β”‚           β”‚ Config  β”‚                      β”‚             β”‚
β”‚ .../app  β”‚           β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜                      β”‚  Output     β”‚
β”‚  12      β”‚                β”‚                           β”‚  *Config    β”‚
β”‚          β”‚           β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”                      β”‚             β”‚
β”‚ .../db   β”‚           β”‚Database β”‚                      β”‚  Inputs     β”‚
β”‚  8       β”‚           β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜                      β”‚  (clickable)β”‚
β”‚          β”‚                β”‚                           β”‚             β”‚
β”‚          β”‚        β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”                   β”‚ [View Deps] β”‚
β”‚          β”‚        β”‚  UserService  β”‚                   β”‚             β”‚
β”‚          β”‚        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β”‚             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Β« Collapse                                           β”‚   Legend    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Three-Panel Layout
Area Description
Left - Package List Provider list grouped by package, searchable, collapsible
Center - Dependency Graph Interactive graph with drag, zoom, click support
Right - Details Panel Show selected node details with clickable navigation

Core Features

The search box on the right side of the toolbar supports:

  • Fuzzy Matching - Enter keywords to match type names or function names
  • Real-time Suggestions - Show matching results dropdown (max 20)
  • Quick Jump - Click result or press Enter to view dependency graph
  • Category Labels - Results marked as Provider or Type
πŸ”„ Bidirectional Dependency Tracking

After searching or clicking a type, the system shows that type as center:

     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚ Upstream β”‚  ← Green nodes
     β”‚ (Config) β”‚
     β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
          β”‚
          β–Ό
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚  Target  β”‚  ← Yellow highlight
     β”‚(Database)β”‚
     β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
          β”‚
          β–Ό
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚Downstreamβ”‚  ← Red nodes
     β”‚(Service) β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Color Legend:

  • 🟑 Yellow - Target node (searched object)
  • 🟒 Green - Dependencies (upstream, what target depends on)
  • πŸ”΄ Red - Dependents (downstream, what depends on target)
πŸ“ Depth Control

Depth determines how many levels to expand up/down:

Depth Description Use Case
1 Only direct dependencies/dependents Quick view of direct relationships
2 Two levels (default) Recommended for daily use
3-5 More levels Track complex dependency chains
All Show complete dependency tree Small projects or specific analysis

Example: Assume dependency chain is Config β†’ Database β†’ UserService β†’ Handler

Search UserService with different depths:

  • Depth 1: Database ← UserService β†’ Handler
  • Depth 2: Config ← Database ← UserService β†’ Handler
🧩 Group Rules (Prefix Aggregation)

You can aggregate nodes by package or prefix using group rules. Rules can be configured:

  • In UI (group list)
  • From backend via RegisterGroupRules (recommended for production)

Backend registration:

import "github.com/pubgo/dix/v2/dixhttp"

dixhttp.RegisterGroupRules(
  dixhttp.GroupRule{
    Name: "service",
    Prefixes: []string{
      "github.com/acme/app/service",
      "github.com/acme/app/internal/service",
    },
  },
  dixhttp.GroupRule{
    Name: "router",
    Prefixes: []string{"github.com/acme/app/router"},
  },
)

The UI will auto-load /api/group-rules if local rules are empty.

πŸ”Ž Prefix Filter

The toolbar provides a Prefix Filter field. It filters the current graph to show only nodes/providers whose package/type/function name contains the given prefix. This works in:

  • Providers/Types view
  • Type-focused dependency view
  • Group subgraph view
🧭 Group Subgraph

Click a virtual group node to open the group detail panel, then click View group graph to see:

  • Internal nodes
  • Upstream & downstream dependencies
  • Depth control applied from the toolbar
πŸ“¦ Package Grouping

Left panel features:

  • Package List - Show all packages with Provider counts
  • Search Filter - Quickly locate specific packages
  • Click Filter - Show only that package's dependencies
  • Collapse - Click Β« button to collapse sidebar, expand graph area

Interactions

Operation Effect
Single Click Show details in right panel
Double Click Show dependency graph centered on that node
Drag Node Move node position
Scroll Zoom Zoom in/out graph
Click Type in Details Jump to view that type's dependencies

API Endpoints

GET /

Returns HTML visualization page

GET /api/stats

Returns summary statistics

{
  "provider_count": 42,
  "object_count": 15,
  "package_count": 8,
  "edge_count": 67
}
GET /api/packages

Returns package list

[
  {
    "name": "github.com/example/app/service",
    "provider_count": 12,
    "types": ["*service.UserService", "*service.OrderService"]
  }
]
GET /api/dependencies?package=xxx&limit=100

Returns dependency data, supports package filtering

{
  "providers": [
    {
      "id": "provider_*main.ServiceA_0",
      "output_type": "*main.ServiceA",
      "output_pkg": "github.com/example/app/service",
      "function_name": "main.NewServiceA",
      "function_pkg": "github.com/example/app",
      "input_types": ["*main.Config"],
      "input_pkgs": ["github.com/example/app/config"]
    }
  ],
  "objects": [...],
  "edges": [...]
}
GET /api/package/{packageName}

Returns Provider details for specified package

GET /api/type/{typeName}?depth=2

Returns dependency chain for specified type

{
  "root_type": "*service.UserService",
  "depth": 2,
  "nodes": [
    {"id": "*service.UserService", "type": "*service.UserService", "package": "...", "level": 0}
  ],
  "edges": [
    {"from": "*db.Database", "to": "*service.UserService", "type": "dependency"}
  ]
}

### GET `/api/group-rules`
Returns backend-registered group rules (used as UI defaults)

```json
[
  {"name": "service", "prefixes": ["github.com/acme/app/service"]}
]

## Tech Stack

- **Backend**: Go standard library `net/http`
- **Frontend**: 
  - [Tailwind CSS](https://tailwindcss.com/) - Styling
  - [Alpine.js](https://alpinejs.dev/) - Reactive interactions
  - [vis-network](https://visjs.github.io/vis-network/) - Graph rendering
- **Template**: Go embed single-file HTML

## Use Cases

βœ… **Recommended**:
- Large projects (100+ providers)
- Modular architecture needing package-based viewing
- Tracking specific type dependency chains
- Debugging circular dependency issues
- Onboarding new team members

⚠️ **Notes**:
- Production environment should restrict access (internal network or dev only)
- Very large projects (1000+ providers) should use depth limits

## Example

See `example/http/main.go` for complete example.

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

This section is empty.

Functions ΒΆ

func Example ΒΆ

func Example(di *dixinternal.Dix)

Example demonstrates how to use the HTTP server for dependency visualization

func RegisterGroupRules ΒΆ

func RegisterGroupRules(rules ...GroupRule)

RegisterGroupRules registers global group rules for visualization. This can be called by business code to predefine group rules.

Types ΒΆ

type DependencyData ΒΆ

type DependencyData struct {
	Providers []ProviderInfo `json:"providers"`
	Objects   []ObjectInfo   `json:"objects"`
	Edges     []EdgeInfo     `json:"edges"`
}

DependencyData represents the structure of dependency information

type EdgeInfo ΒΆ

type EdgeInfo struct {
	From string `json:"from"`
	To   string `json:"to"`
	Type string `json:"type"` // "provider", "object", "dependency"
}

EdgeInfo represents a dependency relationship

type GroupRule ΒΆ

type GroupRule struct {
	Name     string   `json:"name"`
	Prefixes []string `json:"prefixes"`
}

GroupRule defines a group name with prefix list for aggregation.

type ObjectInfo ΒΆ

type ObjectInfo struct {
	ID            string `json:"id"`
	Type          string `json:"type"`
	Group         string `json:"group"`
	IsInitialized bool   `json:"is_initialized"`
}

ObjectInfo contains information about an object instance

type PackageDetailsData ΒΆ

type PackageDetailsData struct {
	Package   string         `json:"package"`
	Providers []ProviderInfo `json:"providers"`
	Edges     []EdgeInfo     `json:"edges"`
}

PackageDetailsData contains detailed information for a package

type PackageInfo ΒΆ

type PackageInfo struct {
	Name          string   `json:"name"`
	ProviderCount int      `json:"provider_count"`
	Types         []string `json:"types"`
}

PackageInfo contains information about a package

type ProviderInfo ΒΆ

type ProviderInfo struct {
	ID           string   `json:"id"`
	OutputType   string   `json:"output_type"`
	OutputPkg    string   `json:"output_pkg"`
	FunctionName string   `json:"function_name"`
	FunctionPkg  string   `json:"function_pkg"`
	InputTypes   []string `json:"input_types"`
	InputPkgs    []string `json:"input_pkgs"`
}

ProviderInfo contains information about a provider

type Server ΒΆ

type Server struct {
	// contains filtered or unexported fields
}

Server provides HTTP endpoints to visualize dependency relationships

func NewServer ΒΆ

func NewServer(dix *dixinternal.Dix) *Server

NewServer creates a new HTTP server for dependency visualization

func NewServerWithOptions ΒΆ

func NewServerWithOptions(dix *dixinternal.Dix, opts ...ServerOption) *Server

NewServerWithOptions creates a new HTTP server with options.

func (*Server) HandleDependencies ΒΆ

func (s *Server) HandleDependencies(w http.ResponseWriter, r *http.Request)

HandleDependencies returns JSON data about providers and objects relationships

func (*Server) HandleGroupRules ΒΆ

func (s *Server) HandleGroupRules(w http.ResponseWriter, r *http.Request)

HandleGroupRules returns global group rules for visualization.

func (*Server) HandleIndex ΒΆ

func (s *Server) HandleIndex(w http.ResponseWriter, r *http.Request)

HandleIndex serves the HTML visualization page

func (*Server) HandlePackageDetails ΒΆ

func (s *Server) HandlePackageDetails(w http.ResponseWriter, r *http.Request)

HandlePackageDetails returns details for a specific package

func (*Server) HandlePackages ΒΆ

func (s *Server) HandlePackages(w http.ResponseWriter, r *http.Request)

HandlePackages returns list of packages for navigation

func (*Server) HandleStats ΒΆ

func (s *Server) HandleStats(w http.ResponseWriter, r *http.Request)

HandleStats returns summary statistics

func (*Server) HandleTypeDetails ΒΆ

func (s *Server) HandleTypeDetails(w http.ResponseWriter, r *http.Request)

HandleTypeDetails returns dependency details for a specific type

func (*Server) ListenAndServe ΒΆ

func (s *Server) ListenAndServe(addr string) error

ListenAndServe starts the HTTP server on the specified address

func (*Server) ServeHTTP ΒΆ

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler interface

type ServerOption ΒΆ

type ServerOption func(*Server)

ServerOption customizes the HTTP server behavior.

func WithBasePath ΒΆ

func WithBasePath(basePath string) ServerOption

WithBasePath sets an optional URL prefix for all routes. Example: "/dix".

type StatsData ΒΆ

type StatsData struct {
	ProviderCount int `json:"provider_count"`
	ObjectCount   int `json:"object_count"`
	PackageCount  int `json:"package_count"`
	EdgeCount     int `json:"edge_count"`
}

StatsData contains summary statistics

type TypeDetailsData ΒΆ

type TypeDetailsData struct {
	RootType string     `json:"root_type"`
	Depth    int        `json:"depth"`
	Nodes    []TypeNode `json:"nodes"`
	Edges    []EdgeInfo `json:"edges"`
}

TypeDetailsData contains dependency details for a type

type TypeNode ΒΆ

type TypeNode struct {
	ID      string `json:"id"`
	Type    string `json:"type"`
	Package string `json:"package"`
	Level   int    `json:"level"`
}

TypeNode represents a type in the dependency graph

Jump to

Keyboard shortcuts

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