DEV Community

Cover image for GoFr: Power Up Your Microservices with This Go Framework
Shahariar Rijon
Shahariar Rijon

Posted on

GoFr: Power Up Your Microservices with This Go Framework

If you're a Go developer looking to build microservices faster and with less hassle, GoFr has got your back. It's an opinionated Go framework designed to streamline development, providing built-in observability tools like health-check and heartbeat URLs, automatic Kubernetes probe support, tracing, metrics, and structured logging. All of this helps you keep an eye on your app’s health effortlessly.

Why GoFr?

Developing production-ready applications can be time-consuming, especially when setting up data sources, logging, and monitoring. GoFr simplifies the process by supporting MySQL, PostgreSQL, Kafka, Google Cloud services, MQTT, and more—so you can focus on building your application’s core logic while GoFr handles the heavy lifting.

GoFr Context: More Than Just Go’s Context Package

GoFr introduces its own GoFr Context, an enhanced version of Go’s built-in context package. While it retains Go’s standard functionality, it also integrates seamlessly with GoFr’s ecosystem, acting as the backbone of every request-response cycle. It manages request-specific attributes and ensures each cycle has a properly configured context, complete with loggers and data stores tailored to your project.

What Makes GoFr Stand Out?

If you’re wondering how GoFr compares to other Go frameworks like Gin, here’s the deal:

  • Database Migrations? Built-in. Unlike Gin, which requires manual database migration handling, GoFr does it for you.

  • CRUD Handlers? Auto-generated. No need to manually set up CRUD operations—GoFr streamlines the process.

  • Tracing and Metrics? Pre-configured. While Gin requires third-party integrations, GoFr provides built-in observability.

Key Features You’ll Love

GoFr comes packed with features that make microservice development smooth and hassle-free:
✅ Logging: Capture everything happening in your app for easy debugging and monitoring.
✅ Flexible Responses: Supports JSON, files, and more for different response needs.
✅ Health Checks & Readiness Monitoring: Ensures your services are always available.
✅ Metrics Exposure: Leverage Prometheus for deep application insights.
✅ Tracing Capabilities: Easily track user requests and system events.
✅ Level-Based Logging: Fine-tune logs for better debugging.

GoFr’s Core Principles

At its heart, GoFr follows these guiding principles:

  • Keep it simple and clean. Readable and maintainable code is key.

  • Favor compile-time checking. Catch errors early and avoid runtime surprises.

  • Seamless integration. Make it easy to connect application modules.

  • Functional programming approach. Focus on modularity and reusability.

  • Avoid code duplication. Keep things DRY (Don’t Repeat Yourself).

  • Log and store data efficiently. Use logs for analysis and decision-making.

Circuit Breaker: Keeping Your Services Resilient

When dealing with distributed systems, network failures and timeouts happen. Instead of endlessly retrying failed requests (which can make things worse), GoFr implements a circuit breaker pattern. This prevents excessive retries and protects your app from unnecessary strain.

Here’s how you can enable the circuit breaker in GoFr:

package main

import (
    "time"
    "gofr.dev/pkg/gofr"
    "gofr.dev/pkg/gofr/service"
)

func main() {
    app := gofr.New()

    app.AddHTTPService("order", "https://order-func",
        &service.CircuitBreakerConfig{
            Threshold: 4,  // Number of failed requests before the circuit breaker trips
            Interval: 1 * time.Second, // How often GoFr checks if the service is back
        },
    )

    app.GET("/order", Get)

    app.Run()
}
Enter fullscreen mode Exit fullscreen mode

This ensures that if a service repeatedly fails, GoFr stops making requests temporarily and only resumes once it detects that the service is healthy again.

Publisher-Subscriber Pattern in GoFr

If you’re working with event-driven architecture, GoFr makes it easy with built-in support for Kafka and Google PubSub. It handles dependency injection using an Inversion of Control (IoC) pattern, ensuring better testability and modularity.

Kafka Integration in GoFr

Here’s how you can configure Kafka in GoFr:

PUBSUB_BACKEND=KAFKA
PUBSUB_BROKER=localhost:9092
CONSUMER_ID=order-consumer
Enter fullscreen mode Exit fullscreen mode

To run Kafka in Docker:

docker run --name kafka-1 -p 9092:9092 \
 -e KAFKA_ENABLE_KRAFT=yes \
 -e KAFKA_CFG_PROCESS_ROLES=broker,controller \
 -e KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093 \
 -e KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true \
 -v kafka_data:/bitnami \
 bitnami/kafka:3.4
Enter fullscreen mode Exit fullscreen mode

Subscribing to Messages

Adding a subscriber in GoFr is as simple as defining an HTTP handler:

package main

import (
    "gofr.dev/pkg/gofr"
)

func main() {
    app := gofr.New()

    app.Subscribe("order-status", func(ctx *gofr.Context) error {
        var orderStatus struct {
            OrderId string `json:"orderId"`
            Status  string `json:"status"`
        }

        err := ctx.Bind(&orderStatus)
        if err != nil {
            ctx.Logger.Error(err)
            return nil
        }

        ctx.Logger.Info("Received order ", orderStatus)
        return nil
    })

    app.Run()
}
Enter fullscreen mode Exit fullscreen mode

Publishing Messages

Publishing messages in GoFr is just as easy:

package main

import (
    "encoding/json"
    "gofr.dev/pkg/gofr"
)

func main() {
    app := gofr.New()

    app.POST("/publish-order", order)

    app.Run()
}

func order(ctx *gofr.Context) (interface{}, error) {
    type orderStatus struct {
        OrderId string `json:"orderId"`
        Status  string `json:"status"`
    }

    order := orderStatus{OrderId: "1234", Status: "shipped"}
    msg, _ := json.Marshal(order)

    ctx.Publisher.Publish("order-status", msg)
    return "Message sent", nil
}
Enter fullscreen mode Exit fullscreen mode

Wrapping Up

GoFr takes the pain out of microservice development by offering built-in tools for observability, database handling, and event-driven architectures. Whether you’re looking for automatic health checks, tracing, logging, or easy-to-use Kafka integration, GoFr has you covered.

Want to see GoFr in action? Give it a try and supercharge your Go development!

Top comments (0)