mirror of
https://github.com/MedUnes/go-kata.git
synced 2026-03-12 21:55:53 +07:00
update links under the root README file
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
# Kata 04: The Interface-Based Middleware Chain
|
||||
**Target Idioms:** Interface Design, Middleware Pattern, Composition over Inheritance
|
||||
**Difficulty:** 🔴 Advanced
|
||||
|
||||
## 🧠 The "Why"
|
||||
Object-oriented developers often reach for class hierarchies and inheritance when building pipelines. In Go, **interfaces enable composition over inheritance**. The unidiomatic approach is to create a `BaseHandler` class with virtual methods. The idiomatic Go way uses small interfaces composed together. This pattern powers `http.Handler`, `io.Reader`, and many standard library patterns - but developers from other ecosystems struggle to see when to split interfaces.
|
||||
|
||||
## 🎯 The Scenario
|
||||
You're building a **real-time analytics pipeline** for user events. Each event must pass through multiple processing stages: validation, enrichment, filtering, and finally storage. New stages will be added frequently. The pipeline must be:
|
||||
- Modular (add/remove stages without rewriting core logic)
|
||||
- Observable (track metrics at each stage)
|
||||
- Recoverable (continue processing after non-critical errors)
|
||||
|
||||
## 🛠 The Challenge
|
||||
Create a middleware chain for processing user events.
|
||||
|
||||
### 1. Functional Requirements
|
||||
* [ ] Process events through a configurable chain of middleware
|
||||
* [ ] Each middleware can modify, filter, or reject events
|
||||
* [ ] Provide metrics (counters, latencies) for each stage
|
||||
* [ ] Support graceful shutdown with context cancellation
|
||||
|
||||
### 2. The "Idiomatic" Constraints (Pass/Fail Criteria)
|
||||
To pass this kata, you **must** strictly adhere to these rules:
|
||||
* [ ] **Small Interfaces:** Define a `Processor` interface with a single method: `Process(context.Context, Event) ([]Event, error)`
|
||||
* [ ] **Middleware Composition:** Each middleware must implement the `Processor` interface and wrap another `Processor`
|
||||
* [ ] **Functional Options:** Configure middleware using functional options (e.g., `WithMetricsCollector()`)
|
||||
* [ ] **Context Propagation:** All middleware must respect context cancellation
|
||||
* [ ] **Zero Global State:** No package-level variables for configuration or state
|
||||
* [ ] **Testable by Design:** Each middleware must be unit-testable in isolation
|
||||
|
||||
## 🧪 Self-Correction (Test Yourself)
|
||||
Test your implementation against these scenarios:
|
||||
1. **The "Infinite Loop":**
|
||||
* Create a middleware that generates 2 events from 1 input
|
||||
* Chain it with a filtering middleware
|
||||
* **Fail Condition:** If events multiply uncontrollably or memory usage grows exponentially
|
||||
2. **The "Context Leak":**
|
||||
* Add a middleware with a 10s timeout
|
||||
* Cancel the context after 1s
|
||||
* **Fail Condition:** If any middleware continues processing after context cancellation
|
||||
3. **The "Interface Pollution":**
|
||||
* Try to add a new middleware that needs access to database connections
|
||||
* **Fail Condition:** If you had to modify the core `Processor` interface to add database methods
|
||||
|
||||
## 📚 Resources
|
||||
* [Go Proverbs by Rob Pike](https://go-proverbs.github.io/)
|
||||
* [The Go Blog: Lexical Scanning in Go](https://blog.golang.org/lexical-scanning)
|
||||
* [Standard Library Inspiration: net/http.Handler](https://pkg.go.dev/net/http#Handler)
|
||||
* [Small Interfaces in the Standard Library](https://medium.com/@cep21/small-interfaces-in-go-1e912a7a7883)
|
||||
48
03-http-middleware/16-http-client-hygiene/README.md
Normal file
48
03-http-middleware/16-http-client-hygiene/README.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Kata 16: The HTTP Client Hygiene Wrapper
|
||||
**Target Idioms:** `net/http` Transport Reuse, Timeouts, Context-First APIs, Response Body Draining
|
||||
**Difficulty:** 🔴 Advanced
|
||||
|
||||
## 🧠 The "Why"
|
||||
“Works locally” HTTP code in Go often fails in prod because people:
|
||||
- use `http.DefaultClient` with no timeouts,
|
||||
- create a new client/transport per request (connection churn),
|
||||
- forget to close bodies (leaks + no keep-alive reuse),
|
||||
- don’t drain bodies (prevents connection reuse).
|
||||
|
||||
This kata is about building a small internal SDK the **Go way**.
|
||||
|
||||
## 🎯 The Scenario
|
||||
Your service calls a downstream API that sometimes returns large error bodies and sometimes hangs.
|
||||
You need:
|
||||
- strict timeouts,
|
||||
- proper cancellation,
|
||||
- safe connection reuse,
|
||||
- structured logs.
|
||||
|
||||
## 🛠 The Challenge
|
||||
Implement:
|
||||
- `type APIClient struct { ... }`
|
||||
- `func (c *APIClient) GetJSON(ctx context.Context, url string, out any) error`
|
||||
|
||||
### 1. Functional Requirements
|
||||
- [ ] Use `http.NewRequestWithContext`.
|
||||
- [ ] Decode JSON on 2xx responses into `out`.
|
||||
- [ ] On non-2xx: read up to N bytes of body and return an error including status code.
|
||||
|
||||
### 2. The "Idiomatic" Constraints (Pass/Fail Criteria)
|
||||
- [ ] **Must NOT** use `http.DefaultClient`.
|
||||
- [ ] **Must** configure timeouts (`Client.Timeout` and/or transport-level timeouts).
|
||||
- [ ] **Must** reuse a single `Transport` (connection pooling).
|
||||
- [ ] **Must** `defer resp.Body.Close()`.
|
||||
- [ ] **Must** drain (at least partially) error bodies to allow connection reuse.
|
||||
- [ ] Use `slog` with fields: method, url, status, latency.
|
||||
|
||||
## 🧪 Self-Correction (Test Yourself)
|
||||
- **If connections spike under load:** you probably rebuild transports.
|
||||
- **If keep-alives don’t work:** you likely didn’t drain/close body.
|
||||
- **If hangs occur:** you likely lack correct timeout configuration.
|
||||
|
||||
## 📚 Resources
|
||||
- https://go.dev/src/net/http/client.go
|
||||
- https://go.dev/src/net/http/transport.go
|
||||
- https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/
|
||||
Reference in New Issue
Block a user