A scalable microservices framework powered by Go, gRPC-Gateway, Prisma, and Kubernetes. It exposes REST, gRPC and Graphql
- βοΈ gRPC + REST (gRPC-Gateway) β Automatically expose RESTful APIs from gRPC services.
- βοΈ Prisma Integration β Efficient database management and migrations.
- βοΈ Kubernetes Ready β Easily deploy and scale with Kubernetes.
- βοΈ TLS Security β Secure gRPC communications with TLS.
- βοΈ Structured Logging β Built-in
zap
logging. - βοΈ Rate Limiting & Authentication β Pre-configured middleware.
- βοΈ Modular & Extensible β Easily extend Thunder for custom use cases.
- βοΈ Thunder CLI - Generate, deploy, and create new projects effortlessly.
- βοΈ Graphql support - Transform grpc services into graphql queries
Thunder is designed for scalable microservices and high-performance API development, particularly suited for:
- gRPC-first APIs with RESTful interfaces via gRPC-Gateway
- GraphQL interfaces via grpc-graphql-gateway for strongly-typed, schema-driven queries
- Critical performance and low-latency applications
- Strongly-typed APIs defined in Protobuf
- Efficient inter-service communication with gRPC
- Kubernetes deployments with built-in service discovery and scaling
- Sidecar-friendly design for Istio/Linkerd environments
- Type-safe queries and zero-downtime migrations
- Multi-database support (PostgreSQL, MySQL, SQLite)
- Auto-generated client library for Go
- Minimalist, modular coreβno unnecessary middleware
- Fast startup and small binary footprint
- Pluggable extensions (auth, metrics, tracing)
- Containerized with Docker, optimized for multi-container pods
- Automatic horizontal scaling and load balancing
- Health checks, liveness/readiness probes built in
- If you need a traditional REST-only API (consider Gin, Fiber, or Echo)
- If you require a feature-heavy, middleware-rich framework
- If youβre deploying a monolithic service outside of Kubernetes
git clone https://github.com/Raezil/Thunder.git
cd Thunder
chmod +x install.sh
./install.sh
Remember to install prerequisites, there is tutorial for this #99
Create a new Thunder application:
thunder init myapp
cd myapp
go mod tidy
Create a .proto
file (e.g., example.proto
):
syntax = "proto3";
package example;
import "google/api/annotations.proto";
import "graphql.proto";
service Example {
rpc SayHello(HelloRequest) returns (HelloResponse) {
option (google.api.http) = {
get: "/v1/example/sayhello"
};
option (graphql.schema) = {
type: QUERY // declare as Query
name: "sayhello" // query name
};
};
}
message HelloRequest {
string name = 1 [(graphql.field) = {required: true}];
}
message HelloResponse {
string message = 1;
}
Use the new scaffold
command to spin up a full CRUD .proto
fileβcomplete with gRPC, REST (gRPC-Gateway) and GraphQL annotations. Pass your fields as a comma-separated list of name:type
pairs:
thunder scaffold -service UserService -entity User -fields "id:string,name:string,email:string,age:int32"
Add your service entry in services.json
:
[
{
"ServiceName": "Example",
"ServiceStruct": "ExampleServiceServer",
"ServiceRegister": "RegisterExampleServer",
"HandlerRegister": "RegisterExampleHandler"
"GraphqlHandlerRegister": "RegisterExampleGraphqlHandler"
}
]
Define your schema in schema.prisma
:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @default(cuid()) @id
name String
email String @unique
}
Generate the service implementation:
thunder generate --proto=example.proto --graphql=true
Start the server:
go run ./cmd/app/server/main.go
Server accessible via HTTP at localhost:8080
and gRPC at localhost:50051
.
cd pkg/services/generated
mockgen -source=yourservice_grpc.pb.go -destination=./yourservice_mock.go
go test ./pkg/db ./pkg/middlewares/ ./pkg/services/ ./pkg/services/generated
This setup configures PgBouncer to connect to a PostgreSQL database using Kubernetes resources.
To regenerate and update the userlist.txt
secret, use the following command to encode the credentials:
echo '"postgres" "postgres"' | base64
Now, update pgbouncer-all.yaml
under the Secret
section with the new base64-encoded value:
apiVersion: v1
kind: Secret
metadata:
name: pgbouncer-secret
type: Opaque
data:
userlist.txt: <BASE64_ENCODED_VALUE> # "postgres" "postgres" in base64
cd cmd
mkdir certs
openssl req -x509 -newkey rsa:4096 -keyout certs/server.key -out certs/server.crt -days 365 -nodes \
-subj "/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
kubectl create secret generic app-secret --from-literal=DATABASE_URL="postgres://postgres:postgres@pgbouncer-service:6432/thunder?sslmode=disable" --from-literal=JWT_SECRET="secret"
kubectl create secret generic postgres-secret --from-literal=POSTGRES_USER=postgres --from-literal=POSTGRES_PASSWORD=postgres --from-literal=POSTGRES_DB=thunder
thunder build
thunder deploy
Check pod status:
kubectl get pods -n default
kubectl describe pod $NAME -n default
- Fork the repository.
- Create a feature branch:
git checkout -b feature-new
- Commit changes:
git commit -m "Added feature"
- Push to your branch:
git push origin feature-new
- Submit a pull request.
β Star the repository if you find it useful!
π§ For support, use GitHub Issues.
Thunder is released under the MIT License.