Add service component: api
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

This commit is contained in:
jordan 2026-02-01 19:34:27 +00:00
parent f7a52080e9
commit 89dd4f836b
14 changed files with 230 additions and 1 deletions

View File

@ -9,6 +9,36 @@ clone:
steps:
# COMPONENT_STEPS_BELOW
# Woodpecker CI step for api service
# Add this step to your .woodpecker.yml
build-api:
image: woodpeckerci/plugin-kaniko
settings:
registry: registry.threesix.ai
repo: test-diag/api
tags:
- latest
- ${CI_COMMIT_SHA:0:8}
context: .
dockerfile: services/api/Dockerfile
cache: true
skip-tls-verify: true
when:
branch: main
event: push
deploy-api:
image: bitnami/kubectl:latest
commands:
- kubectl set image deployment/test-diag-api
api=registry.threesix.ai/test-diag/api:${CI_COMMIT_SHA:0:8}
-n projects
|| echo "No deployment found for api, skipping"
when:
branch: main
event: push
# Do not remove the marker above - component steps are inserted here
verify:

View File

@ -46,4 +46,7 @@ test-diag/
## Components
<!-- Components will be listed here as they're added -->
| Component | Type | Path |
|-----------|------|------|
| **api** | API service | `services/api/` |

View File

@ -1,2 +1,3 @@
# Local development processes
# Components will be added below as they're created
api: cd services/api && make run

View File

@ -1,4 +1,5 @@
go 1.23
use ./pkg
use ./services/api
// Component modules will be added below

17
services/api/.env.example Normal file
View File

@ -0,0 +1,17 @@
# api Service Configuration
# Server
SERVER_PORT=8001
SERVER_HOST=0.0.0.0
# App
APP_NAME=api
APP_ENVIRONMENT=development
APP_DEBUG=true
# Logging
LOG_LEVEL=debug
LOG_FORMAT=text
# Database (if needed)
DATABASE_URL=postgres://dev:dev@localhost:5432/test-diag?sslmode=disable

32
services/api/Dockerfile Normal file
View File

@ -0,0 +1,32 @@
# Build stage
FROM golang:1.23-alpine AS builder
WORKDIR /app
# Copy go workspace files
COPY go.work go.work.sum* ./
COPY pkg/go.mod pkg/go.sum* ./pkg/
COPY services/api/go.mod services/api/go.sum* ./services/api/
# Download dependencies
RUN cd services/api && go mod download
# Copy source
COPY pkg/ ./pkg/
COPY services/api/ ./services/api/
# Build
RUN cd services/api && CGO_ENABLED=0 go build -o /api ./cmd/server
# Production stage
FROM alpine:3.19
RUN apk add --no-cache ca-certificates tzdata
WORKDIR /
COPY --from=builder /api /api
EXPOSE 8001
ENTRYPOINT ["/api"]

34
services/api/Makefile Normal file
View File

@ -0,0 +1,34 @@
.PHONY: build run test lint fmt docker-build clean
SERVICE := api
BINARY := bin/$(SERVICE)
GO_MODULE := github.com/jordan/test-diag
# Build the service binary
build:
go build -o $(BINARY) ./cmd/server
# Run the service locally
run:
go run ./cmd/server
# Run tests
test:
go test -v ./...
# Run linter
lint:
golangci-lint run ./...
# Format code
fmt:
gofmt -w .
goimports -w -local $(GO_MODULE) .
# Build Docker image (run from monorepo root)
docker-build:
docker build -t $(SERVICE):latest -f Dockerfile ../..
# Clean build artifacts
clean:
rm -rf bin/

View File

@ -0,0 +1,18 @@
// Package main is the entry point for the api service.
package main
import (
"github.com/jordan/test-diag/pkg/app"
"github.com/jordan/test-diag/services/api/internal/api"
)
func main() {
// Create application
application := app.New("api", app.WithDefaultPort(8001))
// Register routes
api.RegisterRoutes(application)
// Start server
application.Run()
}

View File

@ -0,0 +1,9 @@
name: api
type: service
port: 8001
path: services/api
dependencies: []
# Add dependencies as needed:
# - postgres
# - redis
# - other-service

5
services/api/go.mod Normal file
View File

@ -0,0 +1,5 @@
module github.com/jordan/test-diag/services/api
go 1.23
require github.com/jordan/test-diag/pkg v0.0.0

View File

@ -0,0 +1,26 @@
package handlers
import (
"net/http"
"github.com/jordan/test-diag/pkg/httpresponse"
"github.com/jordan/test-diag/pkg/logging"
)
// Health handles health check endpoints.
type Health struct {
logger *logging.Logger
}
// NewHealth creates a new Health handler.
func NewHealth(logger *logging.Logger) *Health {
return &Health{logger: logger}
}
// Check returns the service health status.
func (h *Health) Check(w http.ResponseWriter, r *http.Request) {
httpresponse.OK(w, r, map[string]string{
"service": "api",
"status": "healthy",
})
}

View File

@ -0,0 +1,21 @@
// Package api provides HTTP routing and handlers for the api service.
package api
import (
"github.com/jordan/test-diag/pkg/app"
"github.com/jordan/test-diag/services/api/internal/api/handlers"
)
// RegisterRoutes registers all HTTP routes for the service.
func RegisterRoutes(application *app.App) {
logger := application.Logger()
// Initialize handlers
healthHandler := handlers.NewHealth(logger)
// Register API routes
application.Route("/api/v1", func(r app.Router) {
r.Get("/health", healthHandler.Check)
// Add more routes here
})
}

View File

@ -0,0 +1,32 @@
// Package config provides service-specific configuration.
package config
import (
"github.com/jordan/test-diag/pkg/config"
)
// Config extends the base config with api-specific settings.
type Config struct {
config.AppConfig
Server config.ServerConfig
Database config.DatabaseConfig
Logging config.LoggingConfig
// Add service-specific config fields here
}
// Load reads configuration from environment variables.
func Load() (*Config, error) {
if err := config.Init(config.Options{
AppName: "api",
DefaultPort: 8001,
}); err != nil {
return nil, err
}
return &Config{
AppConfig: config.ReadAppConfig(),
Server: config.ReadServerConfig(),
Database: config.ReadDatabaseConfig(),
Logging: config.ReadLoggingConfig(),
}, nil
}

View File