https://github.com/objenious/kitty
A microservice framework extending go-kit
https://github.com/objenious/kitty
Last synced: 5 months ago
JSON representation
A microservice framework extending go-kit
- Host: GitHub
- URL: https://github.com/objenious/kitty
- Owner: objenious
- License: mit
- Created: 2018-06-15T15:40:13.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2021-04-26T12:34:28.000Z (about 5 years ago)
- Last Synced: 2024-11-17T12:07:07.554Z (over 1 year ago)
- Language: Go
- Homepage:
- Size: 55.7 KB
- Stars: 18
- Watchers: 11
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# kitty
[](https://travis-ci.org/objenious/kitty) [](http://godoc.org/github.com/objenious/kitty)
[](https://goreportcard.com/report/github.com/objenious/kitty)
[](https://coveralls.io/github/objenious/kitty?branch=master)
`go get github.com/objenious/kitty`
Kitty is a slightly opinionated framework based on go-kit.
It's goal is to ease development of microservices deployed on Kubernetes (or any similar orchestration platform).
Kitty has an opinion on:
* transports: HTTP only (additional transports can be added as long as they implement kitty.Transport, a Google Pub/Sub transport is available as a separate package),
* errors: an error may be Retryable (e.g. 5XX status codes) or not (e.g. 4XX status codes),
* status codes: unless specified, request decoding errors will generate 400 HTTP status codes.
Kitty has no opinion on:
* logging: no logs are generated by default, you can plug your logger and it will get additional context,
* packages: kitty only imports go-kit and the standard library,
* routers: you can use any router (a Gorilla Mux implementation is available in a sub-package, other routers can easily be plugged),
* encoding: use whatever encoding you want (JSON, messagepack, protobuf, ...),
* monitoring, metrics and tracing: use Istio, a sidecar process or a middleware.
Kitty includes 2 sub-packages:
* backoff: Retryable-aware exponential backoff (only Retryable errors trigger retries),
* circuitbreaker: Retryable-aware circuit breaker (only Retryable errors trigger the circuit breaker).
## Example
Server-side
```
t := kitty.NewHTTPTransport(kitty.Config{HTTPPort: 8081}).
Router(gorilla.Router()).
Endpoint("POST", "/foo", Foo, kitty.Decoder(decodeFooRequest)).
Endpoint("GET", "/bar", Bar)
kitty.NewServer(t).Run(ctx)
// Foo is a go-kit Endpoint
func Foo(ctx context.Context, request interface{}) (interface{}, error) {
fr := request.(fooRequest)
return fooResponse{Message: fmt.Sprintf("Good morning %s !", fr.Name)}, nil
}
// decodeFooRequest
func decodeFooRequest(ctx context.Context, r *http.Request) (interface{}, error) {
var request fooRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}
return request, nil
}
```
Client-side (with circuit breaker & exponential backoff)
```
u, err := url.Parse("http://example.com/foo")
e := kitty.NewClient(
"POST",
u,
kithttp.EncodeJSONRequest,
decodeFooResponse
).Endpoint()
cb := gobreaker.NewCircuitBreaker(gobreaker.Settings{Name: "foo"})
e = kittycircuitbreaker.NewCircuitBreaker(cb)(e)
bo := backoff.NewExponentialBackOff()
e = kittybackoff.NewBackoff(bo)(e)
```
## How-to
### Log requests
```
kitty.NewServer(t).
// Log as JSON
Logger(log.NewJSONLogger(log.NewSyncWriter(os.Stdout))).
// Add path and method to all log lines
LogContext("http-path", "http-method").
// Log request only if an error occurred
Middlewares(kitty.LogEndpoint(kitty.LogErrors))
```
### Integrate with Istio
TBD
### Integrate liveness/readiness checks
Using github.com/heptiolabs/healthcheck:
```
health := healthcheck.NewHandler()
health.AddLivenessCheck("goroutine-threshold", healthcheck.GoroutineCountCheck(100))
health.AddReadinessCheck("database", healthcheck.DatabasePingCheck(db, 1*time.Second))
t := kitty.NewTransport(kitty.Config{}).Liveness(health.LiveEndpoint).Readiness(health.ReadyEndpoint)
```
### Use Google Pub/Sub as a transport
https://github.com/objenious/kitty-gcp adds a Google Pub/Sub transport to kitty:
```
import "github.com/objenious/kitty-gcp/pubsub"
tr := pubsub.NewTransport(ctx, "project-id").
Endpoint(subscriptionName, endpoint, Decoder(decodeFunc))
err := kitty.NewServer(tr).Run(ctx)
```
## Requirements
Go > 1.11
## Contribution guidelines
Contributions are welcome, as long as :
* unit tests & comments are included,
* no external package is added to the top-level package (implementations can be added as sub-packages).
## Thanks
kitty is heavily inspired by gizmo/kit (https://godoc.org/github.com/NYTimes/gizmo/server/kit),
with a different approach to server setup and without the gRPC clutter.
## License
MIT - See LICENSE file