This commit is contained in:
parent
a60bc35c41
commit
b041725ca4
@ -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: composed/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/composed-api
|
||||
api=registry.threesix.ai/composed/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:
|
||||
|
||||
@ -46,4 +46,7 @@ composed/
|
||||
|
||||
## Components
|
||||
|
||||
<!-- Components will be listed here as they're added -->
|
||||
| Component | Type | Path |
|
||||
|-----------|------|------|
|
||||
| **api** | API service | `services/api/` |
|
||||
|
||||
|
||||
1
Procfile
1
Procfile
@ -1,2 +1,3 @@
|
||||
# Local development processes
|
||||
# Components will be added below as they're created
|
||||
api: cd services/api && make run
|
||||
|
||||
1
go.work
1
go.work
@ -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
17
services/api/.env.example
Normal 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/composed?sslmode=disable
|
||||
32
services/api/Dockerfile
Normal file
32
services/api/Dockerfile
Normal 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
34
services/api/Makefile
Normal file
@ -0,0 +1,34 @@
|
||||
.PHONY: build run test lint fmt docker-build clean
|
||||
|
||||
SERVICE := api
|
||||
BINARY := bin/$(SERVICE)
|
||||
GO_MODULE := github.com/jordan/composed
|
||||
|
||||
# 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/
|
||||
18
services/api/cmd/server/main.go
Normal file
18
services/api/cmd/server/main.go
Normal file
@ -0,0 +1,18 @@
|
||||
// Package main is the entry point for the api service.
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/jordan/composed/pkg/app"
|
||||
"github.com/jordan/composed/services/api/internal/api"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Create application
|
||||
application := app.New("api", app.WithDefaultPort(8001))
|
||||
|
||||
// Register routes
|
||||
api.RegisterRoutes(application)
|
||||
|
||||
// Start server
|
||||
application.Run()
|
||||
}
|
||||
9
services/api/component.yaml
Normal file
9
services/api/component.yaml
Normal 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
5
services/api/go.mod
Normal file
@ -0,0 +1,5 @@
|
||||
module github.com/jordan/composed/services/api
|
||||
|
||||
go 1.23
|
||||
|
||||
require github.com/jordan/composed/pkg v0.0.0
|
||||
26
services/api/internal/api/handlers/health.go
Normal file
26
services/api/internal/api/handlers/health.go
Normal file
@ -0,0 +1,26 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/jordan/composed/pkg/httpresponse"
|
||||
"github.com/jordan/composed/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",
|
||||
})
|
||||
}
|
||||
21
services/api/internal/api/routes.go
Normal file
21
services/api/internal/api/routes.go
Normal file
@ -0,0 +1,21 @@
|
||||
// Package api provides HTTP routing and handlers for the api service.
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/jordan/composed/pkg/app"
|
||||
"github.com/jordan/composed/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
|
||||
})
|
||||
}
|
||||
32
services/api/internal/config/config.go
Normal file
32
services/api/internal/config/config.go
Normal file
@ -0,0 +1,32 @@
|
||||
// Package config provides service-specific configuration.
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/jordan/composed/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
|
||||
}
|
||||
0
services/api/migrations/.gitkeep
Normal file
0
services/api/migrations/.gitkeep
Normal file
Loading…
Reference in New Issue
Block a user