REST-APIs mit Go erstellen: Die vollständige Anleitung
Produktionsreife REST-APIs mit Go’s robuster Ökosystem entwickeln
High performante REST-APIs mit Go aufzubauen, hat sich zu einem Standardansatz entwickelt, um Systeme bei Google, Uber, Dropbox und unzähligen Startups anzutreiben.
Gos Einfachheit, die starke Unterstützung von Parallelität und die schnelle Kompilierung machen es ideal für Microservices und Backend-Entwicklung.
Dieses fantastische Bild wurde von FLUX.1-Kontext-dev: Image Augmentation AI Model generiert.
Warum Go für die API-Entwicklung?
Go bietet mehrere überzeugende Vorteile für die API-Entwicklung:
Performance und Effizienz: Go wird zu nativem Maschinencode kompiliert und liefert eine nahezu C-gleiche Performance ohne die damit verbundenen Komplexitäten. Sein effizientes Speichermanagement und die kleinen Binärgrößen machen es perfekt für containerisierte Bereitstellungen.
Integrierte Parallelität: Goroutinen und Channels machen die Handhabung Tausender gleichzeitiger Anfragen straightforward (einfach). Sie können mehrere API-Aufrufe gleichzeitig verarbeiten, ohne komplexen Threading-Code schreiben zu müssen.
Starke Standardbibliothek: Das Paket net/http bietet einen produktionsreifen HTTP-Server direkt aus der Box. Sie können komplette APIs ohne externe Abhängigkeiten erstellen.
Schnelle Kompilierung: Die Kompilierungsgeschwindigkeit von Go ermöglicht schnelle Iterationen während der Entwicklung. Große Projekte werden in Sekunden, nicht in Minuten, kompiliert.
Statische Typisierung mit Einfachheit: Gos Typsystem erkennt Fehler zur Kompilierungszeit und behält gleichzeitig die Codeklarheit. Die Sprache hat ein kleines Funktionsset, das schnell zu erlernen ist.
Ansätze zum Aufbau von APIs in Go
Verwendung der Standardbibliothek
Gos Standardbibliothek bietet alles, was für die grundlegende API-Entwicklung benötigt wird. Hier ist ein minimales Beispiel:
package main
import (
"encoding/json"
"log"
"net/http"
)
type Response struct {
Message string `json:"message"`
Status int `json:"status"`
}
func healthHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(Response{
Message: "API is healthy",
Status: 200,
})
}
func main() {
http.HandleFunc("/health", healthHandler)
log.Println("Server starting on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
Dieser Ansatz bietet volle Kontrolle und null Abhängigkeiten. Er ist ideal für einfache APIs oder wenn Sie die HTTP-Verarbeitung auf fundamentaler Ebene verstehen möchten.
Beliebte Go-Webframeworks
Während die Standardbibliothek leistungsstark ist, können Frameworks die Entwicklung beschleunigen:
Gin: Das beliebteste Go-Webframework, bekannt für seine Performance und Benutzerfreundlichkeit. Es bietet bequemes Routing, Middleware-Unterstützung und Validierung von Anfragen.
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.GET("/users/:id", func(c *gin.Context) {
id := c.Param("id")
c.JSON(http.StatusOK, gin.H{
"user_id": id,
"name": "John Doe",
})
})
r.Run(":8080")
}
Chi: Ein leichter, idiomatischer Router, der sich wie eine Erweiterung der Standardbibliothek anfühlt. Er ist besonders gut geeignet für den Aufbau von RESTful-Diensten mit verschachteltem Routing.
Echo: Hochperformantes Framework mit umfangreicher Middleware und exzellenter Dokumentation. Es ist auf Geschwindigkeit optimiert, bleibt dabei aber developerfreundlich.
Fiber: Inspiriert von Express.js, aufgebaut auf Fasthttp. Es ist die schnellste Option, verwendet jedoch eine andere HTTP-Implementierung als die Standardbibliothek.
Architekturpatterns
Wenn Sie in Go Datenbankoperationen durchführen, müssen Sie Ihre ORM-Strategie berücksichtigen. Verschiedene Projekte haben Ansätze wie GORM, Ent, Bun und sqlc verglichen, wobei jeder unterschiedliche Kompromisse zwischen Entwicklerproduktivität und Performance bietet.
Schichtenarchitektur
Strukturieren Sie Ihre API mit einer klaren Trennung der Verantwortungsbereiche:
// Handler Layer - HTTP concerns
type UserHandler struct {
service *UserService
}
func (h *UserHandler) GetUser(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
user, err := h.service.GetByID(r.Context(), id)
if err != nil {
respondError(w, err)
return
}
respondJSON(w, user)
}
// Service Layer - Business logic
type UserService struct {
repo *UserRepository
}
func (s *UserService) GetByID(ctx context.Context, id string) (*User, error) {
// Validate, transform, apply business rules
return s.repo.FindByID(ctx, id)
}
// Repository Layer - Data access
type UserRepository struct {
db *sql.DB
}
func (r *UserRepository) FindByID(ctx context.Context, id string) (*User, error) {
// Database query implementation
}
Diese Trennung erleichtert das Testen und hält Ihren Code wartbar, während das Projekt wächst.
Domain-Driven Design
Bei komplexen Anwendungen sollten Sie erwägen, Code nach Domänen statt nach technischen Schichten zu organisieren. Jedes Domänenpaket enthält seine eigenen Modelle, Services und Repositories.
Wenn Sie Multi-Tenant-Anwendungen entwickeln, wird das Verständnis von Datenbankmustern für Multi-Tenancy für Ihre API-Architektur entscheidend.
Anfrageverarbeitung und Validierung
Eingabevalidierung
Validieren Sie eingehende Daten immer vor der Verarbeitung:
type CreateUserRequest struct {
Email string `json:"email" validate:"required,email"`
Username string `json:"username" validate:"required,min=3,max=50"`
Age int `json:"age" validate:"gte=0,lte=150"`
}
func (h *UserHandler) CreateUser(w http.ResponseWriter, r *http.Request) {
var req CreateUserRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
respondError(w, NewBadRequestError("Invalid JSON"))
return
}
validate := validator.New()
if err := validate.Struct(req); err != nil {
respondError(w, NewValidationError(err))
return
}
// Process valid request
}
Das Paket go-playground/validator bietet umfangreiche Validierungsregeln und benutzerdefinierte Validatoren.
Anfragekontext
Verwenden Sie Context für anfragespezifische Werte und Abbruch:
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
userID, err := validateToken(token)
if err != nil {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
ctx := context.WithValue(r.Context(), "userID", userID)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
Für eine tiefe Einarbeitung in Context-Best Practices — einschließlich typisierter Keys, Abbruchpropagierung, Timeout-Budgets und graceful shutdown — siehe Go context.Context Done Right.
Authentifizierung und Sicherheit
JWT-basierte Authentifizierung
JSON Web Tokens ermöglichen zustandslose Authentifizierung:
import "github.com/golang-jwt/jwt/v5"
func generateToken(userID string) (string, error) {
claims := jwt.MapClaims{
"user_id": userID,
"exp": time.Now().Add(time.Hour * 24).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(os.Getenv("JWT_SECRET")))
}
func validateToken(tokenString string) (string, error) {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(os.Getenv("JWT_SECRET")), nil
})
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return claims["user_id"].(string), nil
}
return "", err
}
Middleware-Patterns
Implementieren Sie querschnittliche Belange als Middleware:
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
log.Printf("Started %s %s", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
log.Printf("Completed in %v", time.Since(start))
})
}
func rateLimitMiddleware(next http.Handler) http.Handler {
limiter := rate.NewLimiter(10, 20) // 10 requests/sec, burst of 20
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !limiter.Allow() {
http.Error(w, "Rate limit exceeded", http.StatusTooManyRequests)
return
}
next.ServeHTTP(w, r)
})
}
Fehlerbehandlung
Implementieren Sie konsistente Fehlerantworten:
type APIError struct {
Code int `json:"code"`
Message string `json:"message"`
Details string `json:"details,omitempty"`
}
func (e *APIError) Error() string {
return e.Message
}
func NewBadRequestError(message string) *APIError {
return &APIError{
Code: http.StatusBadRequest,
Message: message,
}
}
func NewNotFoundError(resource string) *APIError {
return &APIError{
Code: http.StatusNotFound,
Message: fmt.Sprintf("%s not found", resource),
}
}
func respondError(w http.ResponseWriter, err error) {
apiErr, ok := err.(*APIError)
if !ok {
apiErr = &APIError{
Code: http.StatusInternalServerError,
Message: "Internal server error",
}
// Log the actual error for debugging
log.Printf("Unexpected error: %v", err)
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(apiErr.Code)
json.NewEncoder(w).Encode(apiErr)
}
Für einen tieferen Einblick in die Fehlerarchitektur über Repository-, Service- und Handler-Schichten hinweg — einschließlich Sentinel-Fehlern, benutzerdefinierten Fehlertypen, Grenzübersetzung und sicherer Antwortzuordnung — siehe Go Error Handling Architecture: Boundaries and Patterns.
Datenbankintegration
Verbindungsmanagement
Verwenden Sie Connection Pooling für effizienten Datenbankzugriff:
func initDB() (*sql.DB, error) {
db, err := sql.Open("postgres", os.Getenv("DATABASE_URL"))
if err != nil {
return nil, err
}
db.SetMaxOpenConns(25)
db.SetMaxIdleConns(5)
db.SetConnMaxLifetime(5 * time.Minute)
return db, db.Ping()
}
Abfragemuster
Verwenden Sie vorbereitete Anweisungen und Context für sichere Datenbankoperationen:
func (r *UserRepository) FindByEmail(ctx context.Context, email string) (*User, error) {
query := `SELECT id, email, username, created_at FROM users WHERE email = $1`
var user User
err := r.db.QueryRowContext(ctx, query, email).Scan(
&user.ID,
&user.Email,
&user.Username,
&user.CreatedAt,
)
if err == sql.ErrNoRows {
return nil, ErrUserNotFound
}
return &user, err
}
Teststrategien
Handler-Tests
Testen Sie HTTP-Handler mit httptest:
func TestGetUserHandler(t *testing.T) {
// Setup
mockService := &MockUserService{
GetByIDFunc: func(ctx context.Context, id string) (*User, error) {
return &User{ID: "1", Username: "testuser"}, nil
},
}
handler := &UserHandler{service: mockService}
// Execute
req := httptest.NewRequest("GET", "/users/1", nil)
w := httptest.NewRecorder()
handler.GetUser(w, req)
// Assert
assert.Equal(t, http.StatusOK, w.Code)
var response User
json.Unmarshal(w.Body.Bytes(), &response)
assert.Equal(t, "testuser", response.Username)
}
Integrationstests
Testen Sie komplette Workflows mit einer Testdatenbank:
func TestCreateUserEndToEnd(t *testing.T) {
// Setup test database
db := setupTestDB(t)
defer db.Close()
// Start test server
server := setupTestServer(db)
defer server.Close()
// Make request
body := strings.NewReader(`{"email":"test@example.com","username":"testuser"}`)
resp, err := http.Post(server.URL+"/users", "application/json", body)
require.NoError(t, err)
defer resp.Body.Close()
// Verify response
assert.Equal(t, http.StatusCreated, resp.StatusCode)
// Verify database state
var count int
db.QueryRow("SELECT COUNT(*) FROM users WHERE email = $1", "test@example.com").Scan(&count)
assert.Equal(t, 1, count)
}
API-Dokumentation
OpenAPI/Swagger
Dokumentieren Sie Ihre API mit OpenAPI-Spezifikationen:
// @title User API
// @version 1.0
// @description API for managing users
// @host localhost:8080
// @BasePath /api/v1
// @Summary Get user by ID
// @Description Retrieves a user's information by their ID
// @Tags users
// @Accept json
// @Produce json
// @Param id path string true "User ID"
// @Success 200 {object} User
// @Failure 404 {object} APIError
// @Router /users/{id} [get]
func (h *UserHandler) GetUser(w http.ResponseWriter, r *http.Request) {
// Implementation
}
Verwenden Sie swaggo/swag, um interaktive API-Dokumentation aus diesen Kommentaren zu generieren.
Performanceoptimierung
Antwortkomprimierung
Aktivieren Sie Gzip-Komprimierung für Antworten:
import "github.com/NYTimes/gziphandler"
func main() {
r := chi.NewRouter()
r.Use(gziphandler.GzipHandler)
// Rest of setup
}
Caching
Implementieren Sie Caching für häufig abgerufene Daten:
import "github.com/go-redis/redis/v8"
type CachedUserRepository struct {
repo *UserRepository
cache *redis.Client
}
func (r *CachedUserRepository) GetByID(ctx context.Context, id string) (*User, error) {
// Try cache first
cached, err := r.cache.Get(ctx, "user:"+id).Result()
if err == nil {
var user User
json.Unmarshal([]byte(cached), &user)
return &user, nil
}
// Cache miss - fetch from database
user, err := r.repo.FindByID(ctx, id)
if err != nil {
return nil, err
}
// Store in cache
data, _ := json.Marshal(user)
r.cache.Set(ctx, "user:"+id, data, 10*time.Minute)
return user, nil
}
Connection Pooling
Wiederverwenden Sie HTTP-Verbindungen für externe API-Aufrufe:
var httpClient = &http.Client{
Timeout: 10 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
},
}
Bereitstellungsüberlegungen
Docker-Containerisierung
Erstellen Sie effiziente Docker-Images mit Multi-Stage-Builds:
# Build stage
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o api ./cmd/api
# Production stage
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/api .
EXPOSE 8080
CMD ["./api"]
Dies erzeugt ein minimales Image (typischerweise unter 20 MB) mit nur Ihrer Binärdatei und den essentiellen Zertifikaten.
Konfigurationsmanagement
Verwenden Sie Umgebungsvariablen und Konfigurationsdateien:
type Config struct {
Port string
DatabaseURL string
JWTSecret string
LogLevel string
}
func LoadConfig() (*Config, error) {
return &Config{
Port: getEnv("PORT", "8080"),
DatabaseURL: getEnv("DATABASE_URL", ""),
JWTSecret: getEnv("JWT_SECRET", ""),
LogLevel: getEnv("LOG_LEVEL", "info"),
}, nil
}
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}
Graceful Shutdown
Behandeln Sie Shutdown-Signale richtig:
func main() {
server := &http.Server{
Addr: ":8080",
Handler: setupRouter(),
}
// Start server in goroutine
go func() {
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("Server error: %v", err)
}
}()
// Wait for interrupt signal
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutting down server...")
// Give outstanding requests 30 seconds to complete
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Fatalf("Server forced to shutdown: %v", err)
}
log.Println("Server exited")
}
Monitoring und Observability
Strukturierte Protokollierung
Verwenden Sie strukturierte Protokollierung für bessere Suchbarkeit:
import "go.uber.org/zap"
func setupLogger() (*zap.Logger, error) {
config := zap.NewProductionConfig()
config.OutputPaths = []string{"stdout"}
return config.Build()
}
func (h *UserHandler) GetUser(w http.ResponseWriter, r *http.Request) {
logger := h.logger.With(
zap.String("method", r.Method),
zap.String("path", r.URL.Path),
zap.String("user_id", r.Context().Value("userID").(string)),
)
logger.Info("Processing request")
// Handler logic
}
Zap ist eine solide Wahl, wenn Sie einen reifen Logger von Drittanbietern wünschen. Wenn Sie die Standardbibliothek bevorzugen, bietet log/slog (Go 1.21+) JSON-freundliche Records, Handler-Level-Redaktion und Felder, die mit Traces und Log-Pipelines übereinstimmen. Siehe Structured Logging in Go with slog for Observability and Alerting.
Metrikensammlung
Stellen Sie Prometheus-Metriken bereit:
import "github.com/prometheus/client_golang/prometheus"
var (
requestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "Duration of HTTP requests",
},
[]string{"method", "path", "status"},
)
)
func init() {
prometheus.MustRegister(requestDuration)
}
func metricsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
recorder := &statusRecorder{ResponseWriter: w, status: 200}
next.ServeHTTP(recorder, r)
duration := time.Since(start).Seconds()
requestDuration.WithLabelValues(
r.Method,
r.URL.Path,
strconv.Itoa(recorder.status),
).Observe(duration)
})
}
Fortgeschrittene Patterns
Arbeiten mit strukturierten Ausgaben
Wenn Sie APIs entwickeln, die mit LLMs integriert werden, müssen Sie möglicherweise Antworten mit strukturierter Ausgabe einschränken. Dies ist besonders nützlich für KI-gestützte Funktionen in Ihrer API.
Web Scraping für API-Datenquellen
Wenn Ihre API Daten von anderen Websites aggregieren muss, können das Verständnis von Alternativen zu Beautiful Soup in Go helfen, robuste Web-Scraping-Funktionalität zu implementieren.
Dokumentengenerierung
Viele APIs müssen Dokumente generieren. Für die PDF-Generierung in Go gibt es verschiedene Bibliotheken und Ansätze, die Sie in Ihre API-Endpunkte integrieren können.
Semantische Suche und Reranking
Für APIs, die sich mit Textsuche und -abruf befassen, kann die Implementierung von Reranking mit Embedding-Modellen die Relevanz der Suchergebnisse erheblich verbessern.
Aufbau von MCP-Servern
Wenn Sie APIs implementieren, die dem Model Context Protocol folgen, schauen Sie sich diesen Leitfaden zur Implementierung von MCP-Servern in Go an, der Protokollspezifikationen und praktische Implementierungen abdeckt.
Häufige Fehler und Lösungen
Falsche Verwendung von Contexts
Übergeben und respektieren Sie Context immer in Ihrer gesamten Aufrufkette. Dies ermöglicht eine ordnungsgemäße Abbruch- und Timeout-Verarbeitung.
Ignorieren von Goroutine-Leaks
Stellen Sie sicher, dass alle Goroutinen terminieren können. Verwenden Sie Contexts mit Deadlines und haben Sie immer einen Weg, den Abschluss zu signalisieren.
Schlechte Fehlerbehandlung
Geben Sie keine rohen Datenbankfehler an Clients zurück. Wrappen Sie Fehler mit Context und geben Sie bereinigte Nachrichten in API-Antworten zurück.
Fehlende Eingabevalidierung
Validieren Sie alle Eingaben an der Eintrittsstelle. Vertrauen Sie niemals auf Client-Daten, nicht einmal von authentifizierten Benutzern.
Unzureichendes Testen
Testen Sie nicht nur den „Happy Path". Decken Sie Fehlerfälle, Randbedingungen und Szenarien für gleichzeitigen Zugriff ab.
Zusammenfassung der Best Practices
-
Einfach beginnen: Beginnen Sie mit der Standardbibliothek. Fügen Sie Frameworks hinzu, wenn die Komplexität es erfordert.
-
Schichten Ihrer Anwendung: Trennen Sie HTTP-Handler, Geschäftslogik und Datenzugriff für Wartbarkeit.
-
Alles validieren: Prüfen Sie Eingaben an den Grenzen. Verwenden Sie starke Typisierung und Validierungsbibliotheken.
-
Fehler konsistent behandeln: Geben Sie strukturierte Fehlerantworten zurück. Loggen Sie interne Fehler, exponieren Sie sie aber nicht.
-
Middleware verwenden: Implementieren Sie querschnittliche Belange (Authentifizierung, Protokollierung, Metriken) als Middleware.
-
Gründlich testen: Schreiben Sie Unit-Tests für Logik, Integrationstests für Datenzugriff und End-to-End-Tests für Workflows.
-
API dokumentieren: Verwenden Sie OpenAPI/Swagger für interaktive Dokumentation.
-
Produktion überwachen: Implementieren Sie strukturierte Protokollierung, Metrikensammlung und Health-Checks.
-
Sorgfältig optimieren: Profilen Sie vor der Optimierung. Verwenden Sie Caching, Connection Pooling und Komprimierung dort, wo sie von Vorteil sind.
-
Design für Graceful Shutdown: Behandeln Sie Terminierungssignale und leeren Sie Verbindungen ordnungsgemäß.
Start-Checkliste
Für Referenzzwecke bei Go-Projekten kann eine umfassende Go-Cheatsheet zur Hand sein, um die Entwicklung zu beschleunigen und als schnelle Referenz für Syntax und gängige Patterns zu dienen.
Bereit, Ihre erste Go-API zu bauen? Beginnen Sie mit diesen Schritten:
- ✅ Richten Sie Ihre Go-Umgebung und Projektstruktur ein
- ✅ Wählen Sie zwischen Standardbibliothek oder einem Framework
- ✅ Implementieren Sie grundlegende CRUD-Endpunkte
- ✅ Fügen Sie Anfragevalidierung und Fehlerbehandlung hinzu
- ✅ Implementieren Sie Authentifizierungs-Middleware
- ✅ Fügen Sie Datenbankintegration mit Connection Pooling hinzu
- ✅ Schreiben Sie Unit- und Integrationstests
- ✅ Fügen Sie API-Dokumentation hinzu
- ✅ Implementieren Sie Protokollierung und Metriken
- ✅ Containerisieren Sie mit Docker
- ✅ Richten Sie eine CI/CD-Pipeline ein
- ✅ Stellen Sie mit Monitoring in die Produktion
Fazit
Go bietet eine exzellente Grundlage für den Aufbau von REST-APIs und kombiniert dabei Performance, Einfachheit und robuste Werkzeuge. Ob Sie Microservices, interne Tools oder öffentliche APIs entwickeln, Gos Ökosystem hat reife Lösungen für jeden Bedarf.
Der Schlüssel zum Erfolg liegt darin, mit soliden Architekturmustern zu beginnen, von Anfang an eine ordnungsgemäße Fehlerbehandlung und Validierung zu implementieren und eine umfassende Testabdeckung aufzubauen. Wenn Ihre API wächst, werden Sie von den Performance-Charakteristiken und der starken Parallelitätsunterstützung von Go gut bedient sein.
Denken Sie daran, dass API-Entwicklung iterativ ist. Beginnen Sie mit einer minimalen, machbaren Implementierung, sammeln Sie Feedback und verfeinern Sie Ihren Ansatz basierend auf Nutzungsmustern in der realen Welt. Gos schnelle Kompilierung und unkompliziertes Refactoring machen diesen Iterationszyklus reibungslos und produktiv.
Nützliche Links
- Go Cheat Sheet
- Structured Logging in Go with slog for Observability and Alerting
- Comparing Go ORMs for PostgreSQL: GORM vs Ent vs Bun vs sqlc
- Multi-Tenancy Database Patterns with examples in Go
- Beautiful Soup Alternatives for Go
- Generating PDF in GO - Libraries and examples
- Constraining LLMs with Structured Output: Ollama, Qwen3 & Python or Go
- Reranking text documents with Ollama and Qwen3 Embedding model - in Go
- Model Context Protocol (MCP), and notes on implementing MCP server in Go
Externe Ressourcen
Offizielle Dokumentation
- Go Official Documentation - Die offizielle Go-Dokumentation und Tutorials
- Go net/http Package - Dokumentation des Standardbibliotheks-HTTP-Pakets
- Effective Go - Best Practices für das Schreiben von klarem, idiomatischem Go-Code
Beliebte Frameworks und Bibliotheken
- Gin Web Framework - Schnelles HTTP-Webframework mit umfangreichen Funktionen
- Chi Router - Leichter, idiomatischer Router für den Aufbau von Go-HTTP-Diensten
- Echo Framework - Hochperformantes, erweiterbares, minimalistisches Webframework
- Fiber Framework - Von Express inspiriertes Webframework, aufgebaut auf Fasthttp
- GORM - Die fantastische ORM-Bibliothek für Golang
- golang-jwt - JWT-Implementierung für Go
Test- und Entwicklungswerkzeuge
- Testify - Eine Toolkit mit gängigen Assertions und Mocks
- httptest Package - Standardbibliotheks-Utilities für HTTP-Tests
- Swaggo - Automatisch generierte RESTful-API-Dokumentation
- Air - Live-Reload für Go-Apps während der Entwicklung
Best Practices und Leitfäden
- Go Project Layout - Standard Go-Projektlayouts
- Uber Go Style Guide - Umfassender Go-Styleguide von Uber
- Go Code Review Comments - Häufige Kommentare während Go-Code-Reviews
- REST API Design Best Practices - Allgemeine Prinzipien für das REST-API-Design
Sicherheit und Authentifizierung
- OWASP Go Secure Coding Practices - Sicherheitsrichtlinien für Go-Anwendungen
- OAuth2 for Go - OAuth 2.0-Implementierung
- bcrypt Package - Passwort-Hashing-Implementierung
Performance und Monitoring
- pprof - Eingebautes Profiling-Tool für Go-Programme
- Prometheus Client - Prometheus-Instrumentierungsbibliothek für Go
- Zap Logger - Schnelle, strukturierte, gestaffelte Protokollierung
- App Architecture hub — API design, code structure, and integration patterns