Go로 REST API 구축하기: 완전 가이드
Go의 견고한 생태계를 활용하여 프로덕션 수준의 REST API를 구축하세요
고(Go)를 사용한 고성능 REST API 구축은 Google, Uber, Dropbox 및 수많은 스타트업의 시스템을 구동하는 표준적인 접근 방식으로 자리 잡았습니다.
고의 단순성, 강력한 동시성 지원, 빠른 컴파일 속도는 마이크로서비스 및 백엔드 개발에 이상적입니다.
이 멋진 이미지는 FLUX.1-Kontext-dev: 이미지 증강 AI 모델을 사용하여 생성되었습니다.
왜 API 개발에 고(Go)를 사용해야 할까요?
고는 API 개발에 다음과 같은 설득력 있는 장점을 제공합니다:
성능과 효율성: 고는 네이티브 기계 코드로 컴파일되어 복잡한 절차 없이 C에 가까운 성능을 제공합니다. 효율적인 메모리 관리와 작은 바이너리 크기는 컨테이너 배포에 완벽합니다.
내장된 동시성: 고루틴(Goroutines)과 채널(Channels)을 사용하면 수천 개의 동시 요청을 처리하는 것이 직관적입니다. 복잡한 스레딩 코드 없이도 여러 API 호출을 동시에 처리할 수 있습니다.
강력한 표준 라이브러리: net/http 패키지는 즉시 프로덕션에 사용 가능한 HTTP 서버를 기본 제공합니다. 외부 의존성 없이 완전한 API를 구축할 수 있습니다.
빠른 컴파일: 고의 컴파일 속도는 개발 중 빠른 반복을 가능하게 합니다. 대규모 프로젝트도 몇 분 대신 몇 초 안에 컴파일됩니다.
단순함과 정적 타이핑: 고의 타입 시스템은 컴파일 시 오류를 포착하면서도 코드 가독성을 유지합니다. 언어는 배우기 쉬운 작은 기능 세트를 가지고 있습니다.
고에서 API를 구축하는 방법
표준 라이브러리 사용
고의 표준 라이브러리는 기본 API 개발에 필요한 모든 것을 제공합니다. 다음은 최소한의 예시입니다:
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))
}
이 접근법은 완전한 제어와 제로 의존성을 제공합니다. 단순한 API 또는 HTTP 처리를 근본적인 수준에서 이해하고 싶을 때 이상적입니다.
인기 있는 고 웹 프레임워크
표준 라이브러리가 강력하지만, 프레임워크는 개발 속도를 높일 수 있습니다:
Gin: 가장 인기 있는 고 웹 프레임워크로, 성능과 사용 편의성으로 유명합니다. 편리한 라우팅, 미들웨어 지원, 요청 유효성 검사를 제공합니다.
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: 표준 라이브러리의 확장처럼 느껴지는 경량적이고 관용적인 라우터입니다. 중첩된 라우팅을 갖춘 RESTful 서비스 구축에 특히 뛰어납니다.
Echo: 광범위한 미들웨어와 훌륭한 문서를 갖춘 고성능 프레임워크입니다. 개발자 친화적인 동시에 속도를 최적화했습니다.
Fiber: Express.js에서 영감을 받아 Fasthttp 위에 구축되었습니다. 가장 빠른 옵션이지만 표준 라이브러리보다 다른 HTTP 구현을 사용합니다.
아키텍처 패턴
고에서 데이터베이스 작업을 수행할 때 ORM 전략을 고려해야 합니다. 다양한 프로젝트는 GORM, Ent, Bun, sqlc와 같은 접근법을 비교하며, 각각 개발 생산성과 성능 사이에서 다른 트레이드오프를 제공합니다.
계층형 아키텍처(Layered Architecture)
관심사 분리를 명확하게 하여 API를 구조화하세요:
// 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
}
이러한 분리는 테스트를 용이하게 하며 프로젝트가 성장함에 따라 코드의 유지보수성을 유지합니다.
도메인 주도 설계(Domain-Driven Design)
복잡한 애플리케이션의 경우, 기술적 계층 대신 도메인별로 코드를 구성하는 것을 고려하세요. 각 도메인 패키지는 자체 모델, 서비스, 리포지토리를 포함합니다.
멀티 테넌트 애플리케이션을 구축 중이라면, 멀티 테넌시를 위한 데이터베이스 패턴을 이해하는 것이 API 아키텍처에 있어 중요합니다.
요청 처리 및 유효성 검사
입력 유효성 검사
처리하기 전에 항상 들어오는 데이터를 유효성 검사하세요:
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
}
go-playground/validator 패키지는 광범위한 유효성 검사 규칙과 사용자 정의 검증기를 제공합니다.
요청 컨텍스트(Context)
요청 범위의 값과 취소를 위해 컨텍스트를 사용하세요:
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))
})
}
타입화된 키, 취소 전파, 타임아웃 예산, 그레시풀 샤트다운 등을 포함한 컨텍스트 모범 사례에 대한 심층 분석은 Go context.Context Done Right를 참조하세요.
인증 및 보안
JWT 기반 인증
JSON Web Tokens는 상태 없는(stateless) 인증을 제공합니다:
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
}
미들웨어 패턴
횡단 관심사(Cross-cutting concerns)를 미들웨어로 구현하세요:
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)
})
}
오류 처리
일관된 오류 응답을 구현하세요:
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)
}
리포지토리, 서비스, 핸들러 계층 전반의 오류 아키텍처에 대한 심층 분석(센티널 오류, 사용자 정의 오류 유형, 경계 변환, 안전한 응답 매핑 포함)은 Go Error Handling Architecture: Boundaries and Patterns을 참조하세요.
데이터베이스 통합
연결 관리
효율적인 데이터베이스 액세스를 위해 연결 풀링을 사용하세요:
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()
}
쿼리 패턴
안전한 데이터베이스 작업을 위해 준비된 문(Prepared statements)과 컨텍스트를 사용하세요:
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
}
테스트 전략
핸들러 테스트
httptest를 사용하여 HTTP 핸들러를 테스트하세요:
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)
}
통합 테스트
테스트 데이터베이스로 전체 워크플로우를 테스트하세요:
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 문서화
OpenAPI/Swagger
OpenAPI 사양을 사용하여 API를 문서화하세요:
// @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
}
이러한 주석에서 대화식 API 문서를 생성하려면 swaggo/swag를 사용하세요.
성능 최적화
응답 압축
응답에 gzip 압축을 활성화하세요:
import "github.com/NYTimes/gziphandler"
func main() {
r := chi.NewRouter()
r.Use(gziphandler.GzipHandler)
// Rest of setup
}
캐싱
자주 액세스하는 데이터에 대해 캐싱을 구현하세요:
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
}
연결 풀링
외부 API 호출을 위해 HTTP 연결을 재사용하세요:
var httpClient = &http.Client{
Timeout: 10 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
},
}
배포 고려사항
Docker 컨테이너화
멀티 스테이지 빌드를 사용하여 효율적인 Docker 이미지를 생성하세요:
# 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"]
이로 인해 바이너리와 필수 인증서만 포함된 최소한의 이미지(일반적으로 20MB 미만)가 생성됩니다.
구성 관리
환경 변수와 구성 파일을 사용하세요:
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)
샤트다운 신호를 적절하게 처리하세요:
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")
}
모니터링 및 가시성(Observability)
구조화된 로깅
더 나은 검색 가능성을 위해 구조화된 로깅을 사용하세요:
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은 성숙한 타사 로거가 필요할 때 훌륭한 선택입니다. 표준 라이브러리를 선호한다면, log/slog(Go 1.21+)은 JSON 친화적인 레코드, 핸들러 수준의 삭제(redaction), 추적 및 로그 파이프라인과 일치하는 필드를 제공합니다. Structured Logging in Go with slog for Observability and Alerting을 참조하세요.
메트릭 수집
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)
})
}
고급 패턴
구조화된 출력 작업
LLM과 통합되는 API를 구축할 때, 구조화된 출력으로 응답을 제약해야 할 수 있습니다. 이는 API의 AI 기반 기능에 특히 유용합니다.
API 데이터 소스를 위한 웹 스크래핑
API가 다른 웹사이트에서 데이터를 집계해야 하는 경우, 고에서의 Beautiful Soup 대안을 이해하면 견고한 웹 스크래핑 기능을 구현하는 데 도움이 됩니다.
문서 생성
많은 API가 문서를 생성해야 합니다. 고에서의 PDF 생성을 위해 API 엔드포인트에 통합할 수 있는 여러 라이브러리와 접근법이 있습니다.
시맨틱 검색 및 리랭킹(Reranking)
텍스트 검색 및 검색을 다루는 API의 경우, 임베딩 모델로 리랭킹 구현하면 검색 결과 관련성을 크게 향상시킬 수 있습니다.
MCP 서버 구축
Model Context Protocol을 따르는 API를 구현 중이라면, 프로토콜 사양과 실용적인 구현을 다루는 고에서 MCP 서버 구현 가이드를 확인해 보세요.
일반적인 함정과 해결책
컨텍스트를 적절하게 사용하지 않음
항상 호출 체인 전반에 걸쳐 컨텍스트를 전달하고 존중하세요. 이는 올바른 취소 및 타임아웃 처리를 가능하게 합니다.
고루틴 누수 무시
모든 고루틴이 종료될 수 있도록 하세요. 마감일이 있는 컨텍스트를 사용하고 완료 신호를 보내는 방법을 항상 마련하세요.
부실한 오류 처리
원시 데이터베이스 오류를 클라이언트에 반환하지 마세요. 컨텍스트와 함께 오류를 래핑하고 API 응답에서 정제된 메시지를 반환하세요.
입력 유효성 검사 누락
엔트리 포인트에서 모든 입력을 유효성 검사하세요. 인증된 사용자의 데이터라도 절대 신뢰하지 마세요.
불충분한 테스트
행운의 경로(happy path)만 테스트하지 마세요. 오류 사례, 경계 조건, 동시 액세스 시나리오를 모두 커버하세요.
모범 사례 요약
-
단순하게 시작: 표준 라이브러리부터 시작하세요. 복잡성이 필요할 때 프레임워크를 추가하세요.
-
애플리케이션 계층화: 유지보수성을 위해 HTTP 핸들러, 비즈니스 로직, 데이터 액세스를 분리하세요.
-
모든 것 유효성 검사: 경계에서 입력을 확인하세요. 강력한 타이핑과 유효성 검사 라이브러리를 사용하세요.
-
일관된 오류 처리: 구조화된 오류 응답을 반환하세요. 내부 오류는 로깅하되 노출하지 마세요.
-
미들웨어 사용: 횡단 관심사(인증, 로깅, 메트릭)를 미들웨어로 구현하세요.
-
철저하게 테스트: 로직에 대해 유닛 테스트, 데이터 액세스에 대해 통합 테스트, 워크플로우에 대해 End-to-End 테스트를 작성하세요.
-
API 문서화: 대화식 문서를 위해 OpenAPI/Swagger를 사용하세요.
-
프로덕션 모니터링: 구조화된 로깅, 메트릭 수집, 헬스 체크를 구현하세요.
-
신중하게 최적화: 최적화 전에 프로파일링하세요. 캐싱, 연결 풀링, 압축을 유용한 곳에 사용하세요.
-
그레시풀 샤트다운 설계: 종료 신호를 처리하고 연결을 적절하게 드레인하세요.
시작 체크리스트
고 프로젝트 작업 시 참고용으로, 손에 포괄적인 고 치트시트가 있으면 개발 속도를 높이고 구문 및 일반 패턴에 대한 빠른 참조로 사용할 수 있습니다.
첫 번째 고 API 구축을 준비되셨나요? 다음 단계로 시작하세요:
- ✅ 고 환경 및 프로젝트 구조 설정
- ✅ 표준 라이브러리 또는 프레임워크 선택
- ✅ 기본 CRUD 엔드포인트 구현
- ✅ 요청 유효성 검사 및 오류 처리 추가
- ✅ 인증 미들웨어 구현
- ✅ 연결 풀링과 함께 데이터베이스 통합 추가
- ✅ 유닛 및 통합 테스트 작성
- ✅ API 문서 추가
- ✅ 로깅 및 메트릭 구현
- ✅ Docker로 컨테이너화
- ✅ CI/CD 파이프라인 설정
- ✅ 모니터링과 함께 프로덕션에 배포
결론
고는 성능, 단순성, 강력한 도구를 결합하여 REST API 구축에 훌륭한 기반을 제공합니다. 마이크로서비스, 내부 도구 또는 공개 API를 구축하든, 고 생태계는 모든 요구사항에 대해 성숙한 솔루션을 갖추고 있습니다.
성공의 열쇠는 견고한 아키텍처 패턴으로 시작하고, 처음부터 적절한 오류 처리 및 유효성 검사를 구현하며, 포괄적인 테스트 커버리지를 구축하는 것입니다. API가 성장함에 따라 고의 성능 특성과 강력한 동시성 지원이 여러분에게 큰 도움이 될 것입니다.
API 개발은 반복적임을 기억하세요. 최소한의 실행 가능한 구현으로 시작하고, 피드백을 수집하며, 실제 사용 패턴에 따라 접근법을 다듬으세요. 고의 빠른 컴파일과 직관적인 리팩토링은 이 반복 주기를 매끄럽고 생산적으로 만듭니다.
유용한 링크
- 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
외부 자료
공식 문서
- Go Official Documentation - 공식 고 문서 및 튜토리얼
- Go net/http Package - 표준 라이브러리 HTTP 패키지 문서
- Effective Go - 명확하고 관용적인 고 코드 작성 모범 사례
인기 프레임워크 및 라이브러리
- Gin Web Framework - 광범위한 기능을 갖춘 빠른 HTTP 웹 프레임워크
- Chi Router - 고 HTTP 서비스 구축을 위한 경량적이며 관용적인 라우터
- Echo Framework - 고성능, 확장 가능한 미니멀리스트 웹 프레임워크
- Fiber Framework - Express에서 영감을 받아 Fasthttp 위에 구축된 웹 프레임워크
- GORM - 고를 위한 멋진 ORM 라이브러리
- golang-jwt - 고용 JWT 구현
테스트 및 개발 도구
- Testify - 공통 어설션 및 모크를 갖춘 툴킷
- httptest Package - HTTP 테스트용 표준 라이브러리 유틸리티
- Swaggo - 자동으로 RESTful API 문서 생성
- Air - 개발 중 고 앱 라이브 리로드
모범 사례 및 가이드
- Go Project Layout - 표준 고 프로젝트 레이아웃
- Uber Go Style Guide - Uber에서 제공하는 포괄적인 고 스타일 가이드
- Go Code Review Comments - 고 코드 리뷰 중 일반적인 코멘트
- REST API Design Best Practices - 일반적인 REST API 설계 원칙
보안 및 인증
- OWASP Go Secure Coding Practices - 고 애플리케이션 보안 가이드라인
- OAuth2 for Go - OAuth 2.0 구현
- bcrypt Package - 비밀번호 해싱 구현
성능 및 모니터링
- pprof - 고 프로그램용 내장 프로파일링 도구
- Prometheus Client - 고용 Prometheus 계측 라이브러리
- Zap Logger - 빠르고 구조화된 레벨 기반 로깅
- App Architecture hub — API design, code structure, and integration patterns