Skip to content

Getting Started

A complete HTTP service with idin-core v2: wire the App, define a validated request, and write a controller that uses the repository.

1. Bootstrap (main.go)

go
package main

import (
    "context"

    core "gitlab.finema.co/finema/idin-core/v2"
)

func main() {
    env, err := core.NewEnv()
    if err != nil {
        panic(err)
    }

    db, err := core.NewDatabase(env)
    if err != nil {
        panic(err)
    }
    redis, err := core.NewCache(env)
    if err != nil {
        panic(err)
    }

    app, err := core.NewApp(env,
        core.WithSQL("default", db),
        core.WithCache("default", redis),
    )
    if err != nil {
        panic(err)
    }
    defer app.Shutdown(context.Background())

    e := core.NewHTTPServer(app, &core.HTTPOptions{AllowOrigins: []string{"*"}})
    e.POST("/users", CreateUser)
    e.GET("/users", ListUsers)

    core.StartHTTPServer(e, env)
}

2. Model

go
type User struct {
    ID    uint   `json:"id" gorm:"primarykey"`
    Email string `json:"email"`
    Name  string `json:"name"`
}

func (User) TableName() string { return "users" }

3. Validated request

go
import "gitlab.finema.co/finema/idin-core/v2/valid"

type CreateUserRequest struct {
    Email *string `json:"email"`
    Name  *string `json:"name"`
}

func (r *CreateUserRequest) Valid(ctx core.IContext) core.IError {
    v := valid.New(ctx)
    v.Str("email", r.Email).Required().Email().Unique("users", "email")
    v.Str("name", r.Name).Required().Length(2, 50)
    return v.Error()
}

4. Controller

Everything uses the ambient context — no ctx passed to any method:

go
import "gitlab.finema.co/finema/idin-core/v2/repository"

func CreateUser(c core.IHTTPContext) error {
    var req CreateUserRequest
    if err := c.BindWithValidate(&req); err != nil {
        return err // rendered as {code, message, fields}
    }

    user := User{Email: *req.Email, Name: *req.Name}
    if err := repository.New[User](c).Create(&user); err != nil {
        return err
    }
    return c.JSON(201, user)
}

func ListUsers(c core.IHTTPContext) error {
    page, err := repository.New[User](c).
        Order("id desc").
        Pagination(c.GetPageOptionsWithAllowed("id", "email"))
    if err != nil {
        return err
    }
    return c.JSON(200, page)
}

5. What you get for free

  • Ambient contextc.DB(), c.Cache(), repository.New[User](c) all carry the request's context (deadline/cancel/trace) automatically.
  • Uniform errors — return any core.IError; the server renders {code, message, fields} with the right HTTP status.
  • Panic safety — a panic in a handler becomes a 500, never crashes the server.
  • Graceful shutdownStartHTTPServer drains in-flight requests outside dev.

Maintained by Passakon Puttasuwan & Dev Core Team.