Yokai Framework

repository·main·Indexed 21 days ago

https://github.com/ankorstore/yokai

A modular, observable Go framework for production-grade backend applications. Yokai automates infrastructure boilerplate including dependency injection via Uber Fx, observability (logging, tracing, metrics), and configuration management. It includes specialized modules such as fxcore for application bootstrapping and a dedicated platform HTTP server, fxconfig for environment-based configuration merging, and fxclock for injectable time manipulation in services and tests.

Tokens
149.9K
Snippets
537
Records
644
Agent score
74%

What's inside Yokai

  1. Overview of Fx Http Server features

    main

    The fxhttpserver module integrates an HTTP server into your Uber fx application. Key features include:

    • Automatic Panic Recovery: Prevents the server from crashing on unexpected panics.
    • Automatic Logging and Tracing: Automatically logs request details such as method, path, and duration.
    • Automatic Metrics: Tracks request counts and durations.
    • Flexible Registration: Allows for registering individual handlers, handler groups, and middlewares.
    • HTML Template Rendering: Built-in support for rendering HTML templates.
  2. Overview of Fx MCP Server features

    main

    The fxmcpserver module is an Uber fx module for mark3labs/mcp-go. It allows you to expose a Model Context Protocol (MCP) server from your application with the following built-in capabilities:

    • Automatic Panic Recovery: Prevents the server from crashing on unexpected errors.
    • Observability: Automatic logging and tracing of requests (including method, target, and duration) and automatic metrics (request count and duration).
    • Extensibility: Support for registering MCP resources, resource templates, prompts, and tools.
    • Server Hooks: Ability to register MCP Streamable HTTP and SSE server context hooks.
    • Multiple Transport Options: Expose the MCP server via:
      • Streamable HTTP (remote)
      • HTTP SSE (remote)
      • Stdio (local)
  3. Features of the Fx gRPC Server Module

    main

    The fxgrpcserver module integrates a gRPC server into an Uber fx application, providing several automated capabilities:

    • Automatic panic recovery: Prevents the server from crashing on unexpected panics.
    • Automatic reflection: Enables gRPC reflection for easier debugging and tool integration.
    • Automatic logging and tracing: Captures method names, durations, and status codes.
    • Automatic metrics: Provides built-in observability for server performance.
    • Automatic healthcheck: Integrates health status reporting.
    • Extensibility: Allows manual registration of gRPC server options, interceptors, and services.
  4. Overview of the fxcore module

    main

    The fxcore module is the central component of a Yokai application. It provides a bootstrapper, a dependency injection system (based on Uber's Fx), and a dedicated core HTTP server.

    This core HTTP server runs on a dedicated port (default :8081) and handles platform concerns such as:

    • Dashboard: A UI for application overview.
    • Debug Endpoints: Information about builds, configuration, and loaded modules.
    • Health Check Endpoints: Exposes configured health check probes.
    • Metrics Endpoint: Exposes collected application metrics.

    By using a dedicated server for these concerns, your main application logic remains isolated from platform-level monitoring and debugging traffic.

  5. What is Yokai and how does it work?

    main

    Yokai is a modular and observable Go framework designed to reduce boilerplate in production-grade backend applications. It handles infrastructure concerns like dependency wiring, configuration management, and observability instrumentation so developers can focus on application logic.

    Core Architecture

    Yokai's architecture is built around three main pillars:

    1. Core Modules: These modules automatically preload essential infrastructure, including logging, tracing, metrics, and health check instrumentation. They also expose a private HTTP server used for infrastructure management and debugging.
    2. Extension Modules: These enrich your application with specific features. You can use Yokai's built-in modules, community contrib modules, or your own custom modules. Common extensions include public HTTP/gRPC servers and workers.
    3. Dependency Injection (DI) System: All modules (core and extensions) are integrated into a central DI system (powered by Uber's Fx), which you use to wire together your application logic.

    Underlying Foundations

    Yokai leverages well-known, robust Go libraries to provide its functionality:

  6. Use the Yokai Core Dashboard

    main

    The Yokai core module provides a built-in dashboard accessible at http://localhost:8081. It serves as a central hub for application observability and management.

    Key features include:

    • Application Overview: High-level status of your running service.
    • Tooling & Information: Access to build details, configuration inspection, metrics, and pprof profiling.
    • Health Checks: Direct access to configured health check endpoints.
    • Module Inspection: View information about loaded modules. For example, the fxhttpserver module can expose details such as:
      • Server port
      • Active routes
      • Error handler configuration
  7. How the Fx Core module works

    main

    The fxcore module serves as the foundation for Yokai applications by providing:

    • A Bootstrapper: To plug in Fx modules, provide application services, and start the runtime.
    • Dependency Injection: Built on top of Uber's fx.
    • Core HTTP Server: A dedicated server (default port :8081) that handles platform concerns separately from your main application logic (e.g., an HTTP or gRPC server). This server exposes:
      • Dashboard: A UI for application overview.
      • Metrics: Endpoint for collected metrics.
      • Health Checks: Endpoints for startup, readiness, and liveness probes.
      • Debug Endpoints: Information about config, modules, build, and pprof.

    This separation ensures that sensitive platform information is not exposed to your end-users and allows your application to focus strictly on business logic.

  8. Use different Span Processors

    main

    The module includes four ready-to-use SpanProcessor implementations:

    • NewNoopSpanProcessor(): Asynchronously voids trace spans (default behavior).
    • NewStdoutSpanProcessor(options...): Asynchronously prints trace spans to standard output. Accepts options like stdouttrace.WithPrettyPrint().
    • NewOtlpGrpcSpanProcessor(ctx, conn): Asynchronously sends traces to an OTLP/gRPC collector (e.g., Jaeger, Grafana Tempo). Requires a connection created via NewOtlpGrpcClientConnection(ctx, endpoint).
    • NewTestSpanProcessor(exporter): Synchronously stores traces in memory for testing assertions. Requires an exporter from the tracetest package.
  9. Override configuration values via environment variables

    main

    The module allows overriding specific configuration keys using environment variables. The mapping follows the pattern CONFIG_{KEY_NAME} (where the key is converted to uppercase).

    For example, if you have a configuration key config.substitution=foo, providing the environment variable CONFIG_SUBSTITUTION=bar will override the value to bar.

    package main
    
    import (
    	"fmt"
    	"os"
    	"github.com/ankorstore/yokai/config"
    )
    
    func main() {
    	// Override the 'config.substitution' key
    	os.Setenv("CONFIG_SUBSTITUTION", "bar")
    
    	cfg, _ := config.NewDefaultConfigFactory().Create()
    
    	fmt.Printf("substitution: %s", cfg.GetString("config.substitution")) // substitution: bar
    }
  10. Use env var placeholders in configuration files

    main

    You can reference environment variables directly within your configuration files using the ${ENV_VAR_NAME} placeholder pattern. These values are resolved at runtime.

    Example: If your config contains placeholder: foo-${BAR}-baz and the environment variable BAR=bar is set, the resolved value will be foo-bar-baz.

  11. Register repositories and services using dependency injection

    main

    Yokai uses automatic dependency injection. To make a repository or service available to other parts of your application, register them in your internal/register.go file using fx.Provide(). This allows the DI container to automatically inject dependencies (like *gorm.DB into a repository, or a repository into a service) into constructors.

    func Register() fx.Option {
    	return fx.Options(
    		// services
    		fx.Provide(
    			// gophers repository
    			repository.NewGopherRepository,
    			// gophers service
    			service.NewGopherService,
    		),
    	)
    }