Building a User CRUD API in Kashvi (5 Minutes)
Welcome to Kashvi! If you're a fresher or transitioning from PHP/Laravel, you'll feel right at home. We're going to build a fully functional User API in just a few minutes.
No advanced features (like WebSockets or gRPC) here—just standard, clean RESTful architecture.
1. Create the Project
First, scaffold a fresh project. This creates a ready-to-use folder structure for you.
kashvi new my-api
cd my-apiThis command generates your main.go, app/ folder for logic, database/ for schemas, and a .env file pre-configured for SQLite.
2. Generate the Resource
We need a Model (to represent the user), a Controller (to handle HTTP requests), a Migration (to create the database table), and a Seeder (to add dummy data).
Instead of creating these manually, Kashvi's CLI does it in one command:
kashvi make:resource Userapp/models/user.go: Your data structure.app/controllers/user_controller.go: Where your API logic lives.database/migrations/xxxx_create_users_table.go: Instructions for creating the database table.database/seeders/user_seeder.go: A place to create fake users for testing.
3. Define the Database Table
Open the newly generated migration file inside the database/migrations/ folder and add name and email columns.
func (m *Migration) Up() {
table := m.CreateTable("users")
table.String("name").NotNull()
table.String("email").Unique().NotNull()
}Run the migration to create the table in SQLite:
kashvi migrate4. Write the Controller Logic
Open app/controllers/user_controller.go and implement Store. Kashvi has built-in JSON validation—missing fields will automatically return a 422.
package controllers
import (
"github.com/shashiranjanraj/kashvi/pkg/ctx"
"my-api/app/models"
"my-api/database" // Assuming you export your db connection here
)
func (c *UserController) Store(ctx *ctx.Context) {
var input struct {
Name string `json:"name" validate:"required,min=2"`
Email string `json:"email" validate:"required,email"`
}
if !ctx.BindJSON(&input) {
return
}
user := models.User{Name: input.Name, Email: input.Email}
database.DB.Create(&user)
ctx.Created(user)
}5. Register the Route
Map a URL (like POST /api/users) to the controller. Add this inside your route registration function.
import "my-api/app/controllers"
func RegisterAPI(r *router.Router) {
api := r.Group("/api")
userCtrl := controllers.NewUserController()
api.Post("/users", "users.store", ctx.Wrap(userCtrl.Store))
}6. Run the Server
kashvi serve7. Test It Out
Create a user:
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"name": "Rahul", "email": "rahul@example.com"}'Success response:
{
"name": "Rahul",
"email": "rahul@example.com"
}Validation test (missing email):
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"name": "Rahul"}'Error response:
{
"error": "validation failed",
"details": {
"email": "email is required"
}
}