Tworzenie REST API w Go: kompletny przewodnik
Twórz produkcyjne API REST z użyciem rozbudowanego ekosystemu języka Go
Budowanie wydajnych REST API w Go stało się standardowym podejściem do zasilania systemów w Google, Uber, Dropbox i niezliczonych startupach.
Prostota Go, silne wsparcie dla współbieżności i szybka kompilacja czynią go idealnym do mikroserwisów i rozwoju backendu.
Ten świetny obraz wygenerowany został przez FLUX.1-Kontext-dev: Model AI do rozszerzania obrazów.
Dlaczego Go do rozwoju API?
Go wnosi kilka przekonujących zalet do rozwoju API:
Wydajność i efektywność: Go kompiluje się do natywnego kodu maszynowego, oferując wydajność zbliżoną do C bez jej złożoności. Efektywne zarządzanie pamięcią i małe rozmiary binariów czynią go doskonałym do wdrożeń konteneryzowanych.
Wbudowana współbieżność: Gorutiny i kanały sprawiają, że obsługa tysięcy równoległych żądań staje się prosta. Możesz przetwarzać wiele wywołań API jednocześnie bez złożonego kodu wątków.
Solidna biblioteka standardowa: Pakiet net/http dostarcza produkcyjnie gotowy serwer HTTP od razu po zainstalowaniu. Możesz budować kompletne API bez żadnych zewnętrznych zależności.
Szybka kompilacja: Szybkość kompilacji Go umożliwia szybką iterację podczas rozwoju. Duże projekty kompilują się w sekundy, nie minuty.
Statyczne typowanie z prostotą: System typów Go wykrywa błędy w czasie kompilacji, jednocześnie zachowując klarowność kodu. Język posiada mały zestaw funkcji, który jest szybki do opanowania.
Podejścia do budowania API w Go
Użycie biblioteki standardowej
Biblioteka standardowa Go dostarcza wszystkiego, czego potrzeba do podstawowego rozwoju API. Oto minimalny przykład:
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))
}
To podejście oferuje pełną kontrolę i zero zależności. Jest idealne dla prostych API lub gdy chcesz zrozumieć obsługę HTTP na fundamentalnym poziomie.
Popularne frameworki webowe w Go
Chociaż biblioteka standardowa jest potężna, frameworki mogą przyspieszyć rozwój:
Gin: Najpopularniejszy framework webowy w Go, znany z wydajności i łatwości użycia. Dostarcza wygodnego routingu, wsparcia dla middleware oraz walidacji żądań.
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: Lekki, idiomaticzny router, który czuje się jak rozszerzenie biblioteki standardowej. Jest szczególnie dobry do budowania usług REST z zagnieżdżonym routingiem.
Echo: Framework o wysokiej wydajności z rozbudowanym middleware i doskonałą dokumentacją. Jest zoptymalizowany pod kątem szybkości, pozostając przyjazny dla dewelopera.
Fiber: Zainspirowany Express.js, zbudowany na bazie Fasthttp. To najszybsza opcja, ale wykorzystuje inną implementację HTTP niż biblioteka standardowa.
Aby poznać wyniki pomiarów wydajności, kompromisy związane ze zgodnością z fasthttp oraz tabelę decyzyjną między wszystkimi pięcioma stackami, zobacz Frameworki webowe w Go w 2026: net/http, chi, Gin, Echo, Fiber — porównanie.
Wzorce architektoniczne
Przy pracy z operacjami na bazie danych w Go musisz rozważyć swoją strategię ORM. Różne projekty porównywały podejścia takie jak GORM, Ent, Bun i sqlc, z których każde oferuje różne kompromisy między produktywnością deweloperską a wydajnością.
Architektura warstwowa
Zaprojektuj swoje API z wyraźnym podziałem obowiązków:
// 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
}
Taki podział ułatwia testowanie i utrzymuje kod w stanie podatnym na konserwację wraz z rozwojem projektu.
Projektowanie oparte na dziedzinie
W przypadku złożonych aplikacji rozważ organizację kodu według domeny, a nie warstw technicznych. Każdy pakiet domeny zawiera własne modele, usługi i repozytoria.
Jeśli budujesz aplikacje wielodzierżawcze (multi-tenant), zrozumienie wzorców baz danych dla wielodzierżawczości staje się kluczowe dla architektury Twojego API.
Obsługa żądań i walidacja
Walidacja danych wejściowych
Zawsze waliduj przychodzące dane przed ich przetwarzaniem:
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
}
Pakiet go-playground/validator dostarcza rozbudowane reguły walidacji i własne walidatory.
Kontekst żądania
Używaj kontekstu dla wartości zakresu żądania i anulowania:
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))
})
}
Aby zagłębić się w najlepsze praktyki dotyczące kontekstu — w tym kluczowane typowane, propagację anulowania, budżety limitów czasowych i łagodne wygaszanie — zobacz Go context.Context poprawnie.
Uwierzytelnianie i bezpieczeństwo
Uwierzytelnianie oparte na JWT
JSON Web Tokens zapewniają bezstanowe uwierzytelnianie:
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
}
Wzorce middleware
Implementuj obawy poprzeczne jako 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)
})
}
Obsługa błędów
Implementuj spójne odpowiedzi błędów:
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)
}
Aby poznać głębszy wgląd w architekturę błędów między warstwami repozytorium, usługi i handlera — w tym błędy sentinela, niestandardowe typy błędów, tłumaczenie na granicach i bezpieczne mapowanie odpowiedzi — zobacz [Architektura obsługi błędów w Go: granice i wzorce](https://www.glukhov.org/pl/app-architecture/code-architecture/go-error-handling-architecture/ "Poznaj architekturę obsługi błędów w Go z zawijaniem, błędami sentinela, niestandardowymi typami, errors.Is, errors.As, granicami API, logowaniem i wzorcami produkcyjnymi.").
## Integracja z bazą danych
### Zarządzanie połączeniami
Używaj poolingu połączeń dla efektywnego dostępu do bazy danych:
```go
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()
}
Wzorce zapytań
Używaj instrukcji przygotowanych i kontekstu dla bezpiecznych operacji na bazie danych:
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
}
Strategie testowania
Testowanie handlerów
Testuj handlery HTTP używając 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)
}
Testy integracyjne
Testuj kompletne workflow z testową bazą danych:
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)
}
Dokumentacja API
OpenAPI/Swagger
Dokumentuj swoje API, używając specyfikacji OpenAPI:
// @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
}
Używaj swaggo/swag, aby generować interaktywną dokumentację API z tych komentarzy.
Optymalizacja wydajności
Kompresja odpowiedzi
Włącz kompresję gzip dla odpowiedzi:
import "github.com/NYTimes/gziphandler"
func main() {
r := chi.NewRouter()
r.Use(gziphandler.GzipHandler)
// Rest of setup
}
Cache’owanie
Implementuj cache’owanie dla często dostępnych danych:
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
}
Pooling połączeń
Wielokrotnie używaj połączeń HTTP dla zewnętrznych wywołań API:
var httpClient = &http.Client{
Timeout: 10 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
},
}
Wymagania wdrożeniowe
Konteneryzacja Docker
Twórz efektywne obrazy Docker, używając budowy wieloetapowej:
# 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"]
Tworzy to minimalny obraz (zwykle poniżej 20MB) z wyłącznie Twoim binariem i niezbędnymi certyfikatami.
Zarządzanie konfiguracją
Używaj zmiennych środowiskowych i plików konfiguracyjnych:
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
}
Łagodne wygaszanie (Graceful Shutdown)
Odpowiednio obsługuj sygnały wygaszania:
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")
}
Monitorowanie i obserwowalność
Logowanie strukturalne
Używaj logowania strukturalnego dla lepszej wyszukiwalności:
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 jest solidnym wyborem, gdy chcesz dojrzały logger z trzeciej strony. Jeśli wolisz bibliotekę standardową, log/slog (Go 1.21+) dostarcza przyjaznych dla JSON rekordów, redagowania na poziomie handlera i pól zgodnych ze śladami i potokami logów. Zobacz Logowanie strukturalne w Go z slog dla obserwowalności i alertowania.
Zbieranie metryk
Eksponuj metryki Prometheus:
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)
})
}
Zaawansowane wzorce
Praca ze strukturalnym outputem
Przy budowaniu API, które integrują się z LLM, może być konieczne ograniczenie odpowiedzi strukturalnym outputem. Jest to szczególnie przydatne dla funkcji zasilanych AI w Twoim API.
Web Scraping dla źródeł danych API
Jeśli Twoje API musi agregować dane z innych witryn, zrozumienie alternatyw dla Beautiful Soup w Go może pomóc w implementacji solidnej funkcjonalności scrapingu.
Generowanie dokumentów
Wiele API musi generować dokumenty. W przypadku generowania PDF w Go, istnieje kilka bibliotek i podejść, które możesz zintegrować z końcami swoich punktów API.
Wyszukiwanie semantyczne i Reranking
Dla API zajmujących się wyszukiwaniem i odzyskiwaniem tekstu, implementacja rerankingu z modelami osadzającymi (embedding) może znacząco poprawić trafność wyników wyszukiwania.
Budowanie serwerów MCP
Jeśli implementujesz API zgodne z Model Context Protocol, sprawdź ten przewodnik dotyczący implementacji serwerów MCP w Go, który obejmuje specyfikacje protokołu i praktyczne implementacje.
Częste pułapki i rozwiązania
Nieprawidłowe używanie kontekstów
Zawsze przekazuj i respektuj kontekst w całym łańcuchu wywołań. Pozwala to na prawidłowe anulowanie i obsługę limitów czasowych.
Ignorowanie wycieków gorutin
Upewnij się, że wszystkie gorutiny mogą zakończyć pracę. Używaj kontekstów z terminami i zawsze miej sposób na sygnalizowanie zakończenia.
Słaba obsługa błędów
Nie zwracaj surowych błędów bazy danych do klientów. Zawijaj błędy z kontekstem i zwracaj zsanityzowane komunikaty w odpowiedziach API.
Brak walidacji danych wejściowych
Waliduj wszystkie dane wejściowe na punkcie wejścia. Nigdy nie ufaj danym klienta, nawet od uwierzytelnionych użytkowników.
Niewystarczające testowanie
Nie testuj tylko ścieżki sukcesu. Pokrywaj przypadki błędne, stany graniczne i scenariusze równoległego dostępu.
Podsumowanie najlepszych praktyk
-
Zacznij prosto: Zacznij od biblioteki standardowej. Dodawaj frameworki, gdy złożoność tego wymaga.
-
Warstwuj swoją aplikację: Oddziel handlery HTTP, logikę biznesową i dostęp do danych dla celów podtrzymywalności.
-
Waliduj wszystko: Sprawdzaj dane wejściowe na granicach. Używaj silnego typowania i bibliotek walidacji.
-
Obsługuj błędy konsekwentnie: Zwracaj strukturalne odpowiedzi błędów. Loguj wewnętrzne błędy, ale nie ujawniaj ich.
-
Używaj middleware: Implementuj obawy poprzeczne (uwierzytelnianie, logowanie, metryki) jako middleware.
-
Testuj gruntownie: Piszę testy jednostkowe dla logiki, testy integracyjne dla dostępu do danych i testy end-to-end dla workflow.
-
Dokumentuj swoje API: Używaj OpenAPI/Swagger dla interaktywnej dokumentacji.
-
Monitoruj produkcję: Implementuj logowanie strukturalne, zbieranie metryk i testy zdrowotne.
-
Optymalizuj ostrożnie: Profiluj przed optymalizacją. Używaj cache’owania, poolingu połączeń i kompresji tam, gdzie to korzystne.
-
Projektuj pod kątem łagodnego wygaszania: Obsługuj sygnały zakończenia i prawidłowo drenuj połączenia.
Kontrola początkowa
Dla odniesienia przy pracy nad projektami Go, posiadanie kompleksowej ściągawki do Go pod ręką może przyspieszyć rozwój i służyć jako szybkie odniesienie do składni i powszechnych wzorców.
Gotowy, aby zbudować swoje pierwsze API w Go? Zacznij od tych kroków:
- ✅ Zainstaluj środowisko Go i strukturę projektu
- ✅ Wybierz między biblioteką standardową a frameworkiem
- ✅ Zaimplementuj podstawowe końce CRUD
- ✅ Dodaj walidację żądań i obsługę błędów
- ✅ Zaimplementuj middleware uwierzytelniania
- ✅ Dodaj integrację z bazą danych z poolingiem połączeń
- ✅ Napisz testy jednostkowe i integracyjne
- ✅ Dodaj dokumentację API
- ✅ Zaimplementuj logowanie i metryki
- ✅ Skonteneryzuj z Dockerem
- ✅ Ustaw pipeline CI/CD
- ✅ Wdroż na produkcję z monitorowaniem
Wniosek
Go dostarcza doskonałą podstawę do budowania REST API, łącząc wydajność, prostotę i solidne narzędzia. Czy budujesz mikroserwisy, narzędzia wewnętrzne czy publiczne API, ekosystem Go oferuje dojrzałe rozwiązania dla każdego wymagania.
Kluczem do sukcesu jest rozpoczęcie od solidnych wzorców architektonicznych, wdrożenie odpowiedniej obsługi błędów i walidacji od samego początku oraz budowanie kompleksowego pokrycia testami. W miarę wzrostu Twojego API, cechy wydajnościowe Go i silne wsparcie dla współbieżności będą Ci dobrze służyły.
Pamiętaj, że rozwój API jest procesem iteracyjnym. Zacznij od minimalnej wykonalnej implementacji, zbieraj informację zwrotną i udoskonalaj swoje podejście na podstawie rzeczywistych wzorców użycia. Szybka kompilacja Go i prosta refaktoryzacja sprawiają, że ten cykl iteracji jest płynny i produktywny.
Przydatne linki
- Ściągawka Go
- Logowanie strukturalne w Go z slog dla obserwowalności i alertowania
- Porównanie ORM dla PostgreSQL w Go: GORM vs Ent vs Bun vs sqlc
- Wzorce baz danych dla wielodzierżawczości z przykładami w Go
- Alternatywy dla Beautiful Soup w Go
- Generowanie PDF w GO - Biblioteki i przykłady
- Ograniczanie LLM za pomocą strukturalnego outputu: Ollama, Qwen3 i Python lub Go
- Reranking dokumentów tekstowych za pomocą Ollama i modelu Qwen3 Embedding - w Go
- Model Context Protocol (MCP) i notatki na temat implementacji serwera MCP w Go
Zewnętrzne zasoby
Oficjalna dokumentacja
- Oficjalna dokumentacja Go - Oficjalna dokumentacja i tutoriale Go
- Pakiet Go net/http - Dokumentacja pakietu HTTP z biblioteki standardowej
- Effective Go - Najlepsze praktyki pisania czystego, idiomaticznego kodu Go
Popularne frameworki i biblioteki
- Gin Web Framework - Szybki framework webowy HTTP z rozbudowanymi funkcjami
- Chi Router - Lekki, idiomaticzny router do budowania usług HTTP w Go
- Echo Framework - Wysokowydajny, rozszerzalny, minimalistyczny framework webowy
- Fiber Framework - Framework webowy inspirowany Express, zbudowany na Fasthttp
- GORM - Fantastyczna biblioteka ORM dla Golang
- golang-jwt - Implementacja JWT dla Go
Testy i narzędzia developerskie
- Testify - Zestaw narzędzi z powszechnymi asercjami i mockami
- Pakiet httptest - Narzędzia biblioteki standardowej do testowania HTTP
- Swaggo - Automatyczne generowanie dokumentacji RESTful API
- Air - Live reload dla aplikacji Go podczas rozwoju
Najlepsze praktyki i przewodniki
- Go Project Layout - Standardowe układy projektów Go
- Uber Go Style Guide - Kompleksowy przewodnik stylu Go od Uber
- Go Code Review Comments - Powszechne komentarze dokonywane podczas przeglądów kodu Go
- REST API Design Best Practices - Ogólne zasady projektowania API REST
Bezpieczeństwo i uwierzytelnianie
- OWASP Go Secure Coding Practices - Wytyczne bezpieczeństwa dla aplikacji Go
- OAuth2 for Go - Implementacja OAuth 2.0
- Pakiet bcrypt - Implementacja hashowania haseł
Wydajność i monitorowanie
- pprof - Wbudowane narzędzie profilowania dla programów Go
- Prometheus Client - Biblioteka instrumentacji Prometheus dla Go
- Zap Logger - Szybkie, strukturalne, poziomowane logowanie
- Hub architektur aplikacji — projektowanie API, struktura kodu i wzorce integracji