Kashvi

Docs

โŒ˜K
Getting started

Installation & Quick Start

Install the Kashvi CLI with Go, scaffold a project, configure environment variables, and run your first server.

1. Install Go

Ensure you have Go 1.24 or later (see the framework go.mod).

2. Install Kashvi CLI

go install github.com/shashiranjanraj/kashvi/cmd/kashvi@latest

3. Create a New Project

kashvi new myproject
cd myproject

The CLI scaffolds a complete project structure for you. Here is what gets created:

๐Ÿ“ myproject/
โ”œโ”€โ”€ ๐Ÿ”ทmain.goโ†App entry point โ€” calls app.New().Routes(...).Run()
โ”œโ”€โ”€ ๐Ÿ“ฆgo.modโ†Go module file
โ”œโ”€โ”€ ๐Ÿ”‘.envโ†DB, JWT, port, log settings (gitignored)
โ”œโ”€โ”€ ๐Ÿ”‘.env.exampleโ†Safe version to commit
โ”œโ”€โ”€ ๐Ÿ“app/
โ”‚ โ”œโ”€โ”€ ๐Ÿ“controllers/โ†HTTP handlers โ€” bind DTOs, call repositories
โ”‚ โ”œโ”€โ”€ ๐Ÿ“models/โ†GORM structs with json/validate tags
โ”‚ โ”œโ”€โ”€ ๐Ÿ“repositories/โ†All DB access (FindByID, All, Create, โ€ฆ)
โ”‚ โ”œโ”€โ”€ ๐Ÿ“services/โ†Business logic (optional layer)
โ”‚ โ”œโ”€โ”€ ๐Ÿ“dto/โ†Request/response structs for BindJSON validation
โ”‚ โ””โ”€โ”€ ๐Ÿ“routes/
โ”‚ โ””โ”€โ”€ ๐Ÿ”ทapi.goโ†Register all routes here
โ”œโ”€โ”€ ๐Ÿ“database/
โ”‚ โ”œโ”€โ”€ ๐Ÿ“migrations/โ†Versioned schema changes (AutoMigrate + DropTable)
โ”‚ โ””โ”€โ”€ ๐Ÿ“seeders/โ†Seed data with app.RegisterSeeder
โ””โ”€โ”€ ๐Ÿ“testdata/โ†JSON test scenarios for TestKit
Tip: Every folder has a single responsibility. Controllers never import orm directly โ€” they call repositories.

4. Configure Environment

Projects created with kashvi new already include .env and .env.example (SQLite at database.sqlite by default). You can still copy the example if you need a fresh file:

bash
cp .env.example .env

Edit .env with your database and other settings. Example:

.env
DB_DRIVER=sqlite
DATABASE_DSN=kashvi.db
JWT_SECRET=your-secret-key
APP_PORT=8080
APP_ENV=local
REDIS_ADDR=localhost:6379
LOG_LEVEL=info
DB_LOG_MODE=silent

5. Run Your First Server

Basic Application

A project from kashvi new uses app.New().Routes(routes.RegisterRoutes).Run(). You can also wire routes inline:

main.go (inline routes)
package main

import (
    "net/http"
    "github.com/shashiranjanraj/kashvi/pkg/app"
    "github.com/shashiranjanraj/kashvi/pkg/router"
)

func main() {
    app.New().
        Routes(func(r *router.Router) {
            r.Get("/hello", "hello", func(w http.ResponseWriter, req *http.Request) {
                w.Write([]byte("Hello from Kashvi!"))
            })
        }).
        Run()
}

Run the application (CLI delegates to your project's app.Run()):

go run . serve
# or
kashvi serve

With Database

For database support, add models and migrations:

go
app.New().
    Routes(func(r *router.Router) {
        // routes here
    }).
    AutoMigrate(&User{}).
    Run()

Logging (app and database)

A common need is to see what the app is doing (info logs) and what SQL is running (database logs). Kashvi uses structured logging and supports both.

Environment variables

In .env:

# App log level: debug | info | warn | error (default: info)
LOG_LEVEL=debug

# GORM/SQL log level: silent | error | warn | info (default: silent)
# Use "info" in development to log every query; "silent" in production.
DB_LOG_MODE=info
  • LOG_LEVEL โ€” Controls the application logger (startup, requests, errors). Use debug in development to see route registration and detailed messages; info or warn in production.
  • DB_LOG_MODE โ€” Controls GORM's SQL logging. Use info while developing to see queries and bindings; set to silent or error in production to reduce noise.

In your code

Use the global logger for app-level messages:

Logger usage
import "github.com/shashiranjanraj/kashvi/pkg/logger"

logger.Info("user_created", "user_id", user.ID, "email", user.Email)
logger.Debug("cache_miss", "key", cacheKey)
logger.Warn("rate_limit_approaching", "ip", ip, "count", n)
logger.Error("payment_failed", "error", err, "order_id", orderID)

Arguments are key-value pairs (alternating); they appear as structured fields in the log output.

Request-scoped logs (with request_id)

The framework injects a request_id per request. Use it so you can trace one request across logs:

go
// In a handler that has *http.Request (e.g. after ctx.Wrap, use c.R.Context())
log := logger.WithCtx(c.R.Context())
log.Info("order_created", "order_id", order.ID, "user_id", userID)

If the request passed through reqid.Middleware() and middleware.Logger(), WithCtx returns a logger that already includes request_id. The same ID is logged for that request in the HTTP access line (method, path, status, duration).

Quick reference

GoalWhat to set / use
See app info and debug messagesLOG_LEVEL=debug (or info)
See SQL queries in developmentDB_LOG_MODE=info
Trace one HTTP request in logslogger.WithCtx(r.Context()) in handlers
Log from anywherelogger.Info/Debug/Warn/Error("msg", "key", value)

What's next?