{"id":42237942,"url":"https://github.com/x5iu/defc","last_synced_at":"2026-01-27T03:43:20.650Z","repository":{"id":64535948,"uuid":"576255543","full_name":"x5iu/defc","owner":"x5iu","description":"A Go code generator that automatically generates database CRUD operations, HTTP client code and net/rpc wrappers from interface definitions.","archived":false,"fork":false,"pushed_at":"2025-12-18T07:19:53.000Z","size":379,"stargazers_count":45,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-12-20T07:07:31.010Z","etag":null,"topics":["codegen","database","go","golang","http","sql"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/x5iu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-12-09T11:36:58.000Z","updated_at":"2025-12-18T07:19:50.000Z","dependencies_parsed_at":"2025-12-05T13:02:22.639Z","dependency_job_id":null,"html_url":"https://github.com/x5iu/defc","commit_stats":{"total_commits":84,"total_committers":1,"mean_commits":84.0,"dds":0.0,"last_synced_commit":"b12577dd53bebb3aa1de4909da21e52b77c1f99d"},"previous_names":[],"tags_count":143,"template":false,"template_full_name":null,"purl":"pkg:github/x5iu/defc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x5iu%2Fdefc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x5iu%2Fdefc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x5iu%2Fdefc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x5iu%2Fdefc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/x5iu","download_url":"https://codeload.github.com/x5iu/defc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x5iu%2Fdefc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28800356,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T03:37:11.304Z","status":"ssl_error","status_checked_at":"2026-01-27T03:37:10.427Z","response_time":168,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codegen","database","go","golang","http","sql"],"created_at":"2026-01-27T03:43:19.979Z","updated_at":"2026-01-27T03:43:20.641Z","avatar_url":"https://github.com/x5iu.png","language":"Go","readme":"# defc\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/x5iu/defc.svg)](https://pkg.go.dev/github.com/x5iu/defc)\n[![Go Report Card](https://goreportcard.com/badge/github.com/x5iu/defc)](https://goreportcard.com/report/github.com/x5iu/defc)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nA Go code generator that automatically generates CRUD operations for databases and HTTP client code based on predefined\nschemas.\n\n## Overview\n\n`defc` originates from the tedium of repetitively writing code for \"create, read, update, delete\" (CRUD) operations\nand \"network interface integration\" in daily development work. By defining schemas, defc automatically generates\nboilerplate code for database operations and HTTP requests, including parameter construction, error handling, result\nmapping, and logging logic.\n\nThe name \"defc\" is a combination of \"def\" (define) and \"c\" (CLI - command line interface), reflecting its nature as a\ncommand-line tool for defining and generating code schemas. Currently, defc provides three main code generation scenarios:\n\n- **Database CRUD**: Code generation based on an enhanced fork of [sqlx](https://github.com/jmoiron/sqlx) for database\n  operations\n- **HTTP Client**: Request code generation based on Go's standard `net/http` package\n- **RPC**: Client and server wrappers generation based on Go's standard `net/rpc` package\n\n## Features\n\n- 🚀 **Automatic Code Generation**: Generate database CRUD, HTTP client, and net/rpc wrappers from interface definitions\n- 📊 **SQL Query Support**: Full support for complex SQL queries with template functionality\n- 🌐 **HTTP Client Generation**: Generate HTTP client code with request/response handling\n- 🔧 **Template Engine**: Built-in template support for dynamic SQL and HTTP requests\n- 🎯 **Transaction Support**: Automatic transaction handling for database operations\n- 📝 **Logging Integration**: Built-in logging support for queries and requests\n- 🔄 **Pagination Support**: Automatic pagination handling for HTTP APIs\n- 🎨 **Flexible Configuration**: Multiple configuration options and feature flags\n- 📁 **File Inclusion**: Support for including external SQL files and scripts\n- 🔍 **Type Safety**: Generate type-safe code with proper error handling\n\n\u003e **✨ Enhanced Features**: Starting from v1.37.0, `sqlx/future` and `api/future` features are enabled by default,\n\u003e providing enhanced capabilities and improved interfaces. Use the `legacy` build tag to disable these features if needed.\n\n## Installation\n\n```bash\ngo install github.com/x5iu/defc@latest\n```\n\nOr use with `go run`:\n\n```bash\ngo run -mod=mod github.com/x5iu/defc@latest --help\n```\n\n## Quick Start\n\n### Database CRUD (sqlx mode)\n\n1. Define your schema interface:\n\n```go\n//go:generate go run -mod=mod \"github.com/x5iu/defc\" --mode=sqlx --output=query.go\ntype Query interface {\n// CreateUser EXEC\n// INSERT INTO `user` (`name`, `age`) VALUES (?, ?);\nCreateUser(ctx context.Context, user *User) error\n\n// GetUser QUERY\n// SELECT * FROM `user` WHERE `id` = ?;\nGetUser(ctx context.Context, id int64) (User, error)\n\n// GetUsers QUERY\n// SELECT * FROM `user` WHERE `id` IN ({{ bindvars $.ids }});\nGetUsers(ctx context.Context, ids []int64) ([]*User, error)\n}\n```\n\n2. Run code generation:\n\n```bash\ngo generate\n```\n\n3. Use the generated code:\n\n```go\n// Option 1: Create with driver name and DSN\nquery := NewQuery(\"mysql\", \"connection_string\")\nuser, err := query.GetUser(context.Background(), 1)\n\n// Option 2: Create from existing *sqlx.DB\ndb, _ := sqlx.Open(\"mysql\", \"connection_string\")\nquery := NewQueryFromCore(db)\nuser, err := query.GetUser(context.Background(), 1)\n```\n\n### HTTP Client (api mode)\n\n1. Define your API schema:\n\n```go\n//go:generate go run -mod=mod \"github.com/x5iu/defc\" --mode=api --output=service.go\ntype Service interface {\nOptions() *Config\nResponseHandler() *Response\n\n// CreateUser POST {{ $.Service.Host }}/user\n// Content-Type: application/json\n//\n// {\n//   \"name\": {{ $.name }},\n//   \"age\": {{ $.age }}\n// }\nCreateUser(ctx context.Context, name string, age int) (*User, error)\n\n// GetUsers GET {{ $.Service.Host }}/users?page={{ page }}\nGetUsers(ctx context.Context) ([]*User, error)\n}\n```\n\n2. Run code generation:\n\n```bash\ngo generate\n```\n\n3. Use the generated code:\n\n```go\nconfig := \u0026Config{\nHost:   \"https://api.example.com\",\nAPIKey: \"your-api-key\",\n}\nservice := NewService(config)\nuser, err := service.CreateUser(context.Background(), \"John\", 25)\n```\n\n### RPC (rpc mode)\n\n1. Define your RPC schema:\n\n```go\n//go:generate go run -mod=mod \"github.com/x5iu/defc\" --mode=rpc --output=arith.gen.go\n// Methods must have exactly 1 input and 2 outputs (second is error)\ntype Arith interface {\n    Multiply(args chan int) (int, error)\n}\n```\n\n2. Run code generation:\n\n```bash\ngo generate\n```\n\n3. Use the generated code:\n\n```go\n// Client side\ncli := rpc.NewClient(conn)\narith := NewArith(cli)\nres, err := arith.Multiply(make(chan int))\n\n// Server side (wrap implementation)\nsrv := rpc.NewServer()\nsrv.RegisterName(\"Arith\", NewArithServer(\u0026arithImpl{}))\n```\n\n## Documentation\n\n### Quick Usage\n\n```bash\n# Simplest usage - auto-detect everything\ndefc generate schema.go\n\n# With custom output file\ndefc generate --output=query.go schema.go\n\n# With specific features\ndefc generate --features=sqlx/log,sqlx/rebind schema.go\n```\n\n**Smart Defaults:** The `defc generate` command provides intelligent defaults:\n\n- **Auto-detect mode** by analyzing your interface methods\n- **Auto-generate output filename** as `\u003csource-file\u003e.gen.go` when `--output` is not specified\n- **sqlx mode** is detected when methods contain `EXEC`/`QUERY` operations, or when `WithTx` method is present\n- **api mode** is detected when methods contain HTTP method names (GET, POST, etc.), or when `Options()`/\n  `ResponseHandler()` methods are present\n- **rpc mode** is detected when interface methods each have exactly 1 input parameter and 2 outputs, with the second being `error`\n\n### Available Modes\n\n- `sqlx`: Generate database CRUD operations using sqlx\n- `api`: Generate HTTP client code\n- `rpc`: Generate net/rpc client and server wrappers\n\n### Command Line Options\n\n#### Global Flags\n\n| Flag                    | Short | Type     | Description                                                                  |\n|-------------------------|-------|----------|------------------------------------------------------------------------------|\n| `--mode`                | `-m`  | string   | Generation mode: `sqlx`, `api`, or `rpc` (auto-detected in `generate` command) |\n| `--output`              | `-o`  | string   | Output file name (auto-generated as `\u003csource\u003e.gen.go` in `generate` command) |\n| `--features`            | `-f`  | []string | Enable specific features (see Features section above)                        |\n| `--import`              |       | []string | Additional import packages                                                   |\n| `--func` / `--function` |       | []string | Additional template functions (format: `name=function`)                      |\n| `--disable-auto-import` |       | bool     | Disable automatic import detection                                           |\n| `--help`                | `-h`  |          | Show help information                                                        |\n| `--version`             | `-v`  |          | Show version information                                                     |\n\n#### Generate Command Flags\n\n| Flag         | Short | Type   | Description                                                      |\n|--------------|-------|--------|------------------------------------------------------------------|\n| `--type`     | `-T`  | string | Specify the target interface type when multiple candidates exist |\n| `--template` | `-t`  | string | Additional template content (sqlx mode only, experimental)       |\n\n#### Usage Examples\n\n```bash\n# Basic usage with explicit mode\ndefc --mode=sqlx --output=query.go\n\n# Using generate command (auto-detect mode and output)\ndefc generate schema.go\n\n# With features and custom imports\ndefc generate --features=sqlx/log,sqlx/rebind --import=\"fmt\" schema.go\n\n# Specify target type when multiple interfaces exist\ndefc generate --type=UserQuery user_schema.go\n\n# Custom template (experimental, sqlx only)\ndefc generate --template=\"SELECT * FROM {{ .table }}\" --type=MyQuery schema.go\n```\n\n### Features\n\n#### sqlx Mode Features\n\n**Note:** defc uses an enhanced fork of sqlx that provides additional interfaces and optimizations. Since v1.37.0,\n`sqlx/future` is enabled by default. To use legacy behavior, build with the `legacy` tag: `go build -tags=legacy`.\n\n- `sqlx/log`: Enable query logging\n- `sqlx/rebind`: Automatic parameter placeholder rebinding for different databases\n- `sqlx/in`: Enhanced IN query support\n- `sqlx/future`: Use enhanced sqlx fork (`github.com/x5iu/defc/sqlx`) with additional interfaces and improvements *(\n  enabled by default since v1.37.0)*\n- `sqlx/callback`: Support for callback methods automatically executed after query completion\n- `sqlx/any-callback`: Support for callback methods with flexible executor interface\n- `sqlx/nort`: Generate code without runtime dependencies\n\n#### api Mode Features\n\n**Note:** Since v1.37.0, `api/future` is enabled by default, providing enhanced response handling capabilities. To use\nlegacy behavior, build with the `legacy` tag: `go build -tags=legacy`.\n\n- `api/log`: Enable request logging\n- `api/logx`: Enhanced logging with request/response details\n- `api/client`: Custom HTTP client support\n- `api/cache`: Response caching functionality\n- `api/page`: Automatic pagination support\n- `api/error`: Enhanced error handling with HTTP status codes\n- `api/future`: Use enhanced response handling with `FromResponse()` method *(enabled by default since v1.37.0)*\n- `api/get-body`: Enable access to request body copy via `http.Request.GetBody()` for debugging and logging\n- `api/nort`: Generate code without runtime dependencies\n\n#### rpc Mode Features\n\n- `rpc/nort`: Generate code without runtime dependency on defc runtime helpers (uses reflection-based zero value helpers in generated code)\n- Generated client constructor: `New{Interface}(client *rpc.Client) {Interface}`\n- Generated server wrapper: `New{Interface}Server(impl {Interface}) *{Interface}Server`\n- Method signature rules: exactly 1 input parameter and 2 outputs, with the second being `error`\n\n### Schema Definition\n\n#### sqlx Schema Format\n\n```go\ntype Query interface {\n// MethodName OPERATION [ARGUMENTS]\n// SQL_STATEMENT\nMethodName(ctx context.Context, params...) (result, error)\n}\n```\n\n**Operations:**\n\n- `EXEC`: For INSERT, UPDATE, DELETE operations\n- `QUERY`: For SELECT operations\n\n**Arguments:**\n\n- `NAMED`: Use named parameters (`:param`)\n- `MANY`: Use `sqlx.Select` for multiple results\n- `ONE`: Use `sqlx.Get` for single result\n- `CONST`: Disable template processing for better performance\n- `CONSTBIND`: Use `${expr}` syntax for compile-time parameter binding without template rendering\n- `BIND`: Use binding mode for parameters\n- `SCAN(expr)`: Custom scan target\n- `WRAP=func`: Wrap the query with a custom function\n- `ISOLATION=level`: Set transaction isolation level\n- `ARGUMENTS=var`: Use custom arguments variable\n\n#### api Schema Format\n\n```go\ntype Service interface {\nOptions() *Config\nResponseHandler() *Response\n\n// MethodName HTTP_METHOD [ARGUMENTS] URL\n// HEADERS\n//\n// BODY\nMethodName(ctx context.Context, params...) (result, error)\n}\n```\n\n#### ResponseHandler Interface\n\nThe `ResponseHandler()` method must return a type that implements the Response interface with the following methods:\n\n- **`Err() error`**: Checks if the response contains an error (e.g., non-200 status codes)\n- **`ScanValues(...any) error`**: Scans response data into target objects (similar to `sql.Rows.Scan`)\n- **`FromBytes(method string, data []byte) error`**: Processes response from raw bytes (traditional approach)\n- **`FromResponse(method string, resp *http.Response) error`**: Processes response from HTTP response object (enabled by\n  default since v1.37.0)\n- **`Break() bool`**: Controls pagination flow - return `true` to stop pagination, `false` to continue\n\n**HTTP Methods:** GET, POST, PUT, DELETE, PATCH, etc.\n\n**Arguments:**\n\n- `MANY`: For paginated results (returns slice)\n- `ONE`: For single result (returns single value)\n- `Scan(expr)`: Custom scan parameters for response processing\n- `Options(expr)`: Custom request options\n- `Retry=N`: Set maximum retry attempts (default: 2)\n\n## Advanced Template Features\n\n### SQL File Inclusion\n\nThe `sqlx` mode supports including external SQL files and script output using special directives:\n\n#### #INCLUDE Directive\n\nInclude external SQL files or use glob patterns:\n\n```go\n//go:generate go run -mod=mod \"github.com/x5iu/defc\" --mode=sqlx --output=user_query.go\ntype UserQuery interface {\n// GetUser QUERY ONE\n// #INCLUDE \"queries/get_user.sql\"\nGetUser(ctx context.Context, id int64) (*User, error)\n\n// GetActiveUsers QUERY MANY\n// #INCLUDE \"queries/*.sql\"  // Include all SQL files\nGetActiveUsers(ctx context.Context) ([]*User, error)\n}\n```\n\n#### #SCRIPT Directive\n\nExecute shell commands and include their output:\n\n```go\ntype UserQuery interface {\n// ListUsers QUERY MANY\n// #SCRIPT cat \"queries/list_users.sql\"\nListUsers(ctx context.Context) ([]*User, error)\n\n// GetUserCount QUERY ONE\n// #SCRIPT echo \"SELECT COUNT(*) as count FROM users\"\nGetUserCount(ctx context.Context) (int64, error)\n}\n```\n\n### Template Debugging\n\n#### Syntax Validation\n\ndefc automatically validates template syntax and provides detailed error messages:\n\n```go\n// Invalid template will show clear error\ntype UserQuery interface {\n// GetUser QUERY ONE\n// SELECT * FROM users WHERE id = {{ .invalid_function }};\nGetUser(ctx context.Context, id int64) (*User, error)\n}\n```\n\nError output:\n\n```\nError: template: defc(sqlx):1:45: executing \"GetUser\" at \u003c.invalid_function\u003e: \ncan't evaluate field invalid_function in type map[string]interface {}\n```\n\n### Advanced Template Patterns\n\n#### Conditional Rendering\n\n```go\ntype UserQuery interface {\n// GetUsers QUERY MANY\n// SELECT * FROM users\n// WHERE 1=1\n// {{if $.name}} AND name = {{ bind $.name }}{{end}}\n// {{if $.age}} AND age \u003e= {{ bind $.age }}{{end}}\nGetUsers(ctx context.Context, name string, age int) ([]*User, error)\n}\n```\n\n#### Loop Processing\n\n```go\ntype UserQuery interface {\n// GetUsersByIDs QUERY MANY\n// SELECT * FROM users WHERE id IN ({{ bindvars $.ids }})\nGetUsersByIDs(ctx context.Context, ids []int64) ([]*User, error)\n\n// BulkInsertUsers EXEC\n// INSERT INTO users (name, email) VALUES\n// {{range $i, $user := $.users}}\n//   {{if $i}},{{end}}({{ bind $user.Name }}, {{ bind $user.Email }})\n// {{end}}\nBulkInsertUsers(ctx context.Context, users []*User) error\n}\n```\n\n### Additional Template Content\n\nThe `--template` parameter (sqlx mode only, experimental) allows you to define additional template content that can be\nshared across all methods in your interface.\n\n#### Usage Formats\n\n**Format 1: Template File Path**\n\n```bash\ndefc generate --template path/to/template.tmpl schema.go\n```\n\n**Format 2: Direct Template Expression (with `:` prefix)**\n\n```bash\n# Using string literal (requires quotes)\ndefc generate --template ':\"{{ define \\\"common\\\" }}SELECT * FROM {{ .table }}{{ end }}\"' schema.go\n\n# Using variable reference (no quotes needed)\ndefc generate --template ':templateVar' schema.go\n```\n\n#### Template File Example\n\nCreate a template file `templates/common.tmpl`:\n\n```go\n{{ define \"audit_header\" }}\n/* Generated by defc - Method: {{ .method }} */\n{{ end }}\n\n{{ define \"pagination\" }}\nLIMIT {{ .limit }} OFFSET {{ .offset }}\n{{ end }}\n\n{{ define \"where_active\" }}\nWHERE active = 1 AND deleted_at IS NULL\n{{ end }}\n```\n\nUse in your schema:\n\n```go\n//go:generate defc generate --template templates/common.tmpl --features sqlx/log -o user.gen.go\ntype UserQuery interface {\n// GetUsers QUERY MANY\n// {{ template \"audit_header\" . }}\n// SELECT * FROM users\n// {{ template \"where_active\" }}\n// ORDER BY created_at DESC\n// {{ template \"pagination\" . }}\nGetUsers(ctx context.Context, limit, offset int) ([]*User, error)\n\n// GetActiveUserCount QUERY ONE\n// {{ template \"audit_header\" . }}\n// SELECT COUNT(*) FROM users {{ template \"where_active\" }}\nGetActiveUserCount(ctx context.Context) (int64, error)\n}\n```\n\n#### Direct Template Expression Example\n\n```go\n//go:generate defc generate --template ':\"{{ define \\\"timestamp\\\" }}/* Generated at {{ .now }} */{{ end }}\"' --function now=time.Now -o user.gen.go\ntype UserQuery interface {\n// GetUser QUERY ONE\n// {{ template \"timestamp\" . }}\n// SELECT * FROM users WHERE id = ?;\nGetUser(ctx context.Context, id int64) (*User, error)\n}\n```\n\n#### Advanced Template with Bind Mode\n\nWhen using `bind` function in templates, the system automatically enables `BIND` mode for all methods:\n\n```go\n//go:generate defc generate --template ':\"{{ define \\\"bulk_insert\\\" }}INSERT INTO {{ .table }} ({{ .fields }}) VALUES {{ range $i, $item := .items }}{{ if $i }},{{ end }}({{ range $j, $field := .fields }}{{ if $j }},{{ end }}{{ bind (index $item $field) }}{{ end }}){{ end }}{{ end }}\"' -o bulk.gen.go\ntype BulkQuery interface {\n// BulkInsertUsers EXEC\n// {{ template \"bulk_insert\" . }}\nBulkInsertUsers(ctx context.Context, users []*User) error\n}\n```\n\n#### Template with Custom Functions\n\n```bash\ndefc generate --template ':\"{{ define \\\"custom_log\\\" }}/* {{ logLevel . }} */{{ end }}\"' --function logLevel=getLogLevel schema.go\n```\n\n#### Important Notes\n\n- **sqlx mode only**: The `--template` parameter only works in sqlx mode, not in api mode\n- **Experimental feature**: This is an experimental parameter that may change in future versions\n- **Shared scope**: Templates are shared across all methods in the interface\n- **Auto-bind detection**: If templates use the `bind` function, BIND mode is automatically enabled for all methods\n- **Performance consideration**: Using `bind` in templates adds runtime overhead as templates are parsed on each call\n\n## Examples\n\n### Database Examples\n\n#### Basic CRUD Operations\n\n```go\n//go:generate go run -mod=mod \"github.com/x5iu/defc\" --mode=sqlx --output=user_query.go\ntype UserQuery interface {\n// CreateUser EXEC\n// INSERT INTO users (name, email, age) VALUES (?, ?, ?);\nCreateUser(ctx context.Context, name, email string, age int) error\n\n// GetUserByID QUERY ONE\n// SELECT * FROM users WHERE id = ?;\nGetUserByID(ctx context.Context, id int64) (*User, error)\n\n// GetUsersByAge QUERY MANY\n// SELECT * FROM users WHERE age \u003e= ? ORDER BY name;\nGetUsersByAge(ctx context.Context, minAge int) ([]*User, error)\n\n// UpdateUser EXEC\n// UPDATE users SET name = ?, email = ? WHERE id = ?;\nUpdateUser(ctx context.Context, name, email string, id int64) error\n\n// DeleteUser EXEC\n// DELETE FROM users WHERE id = ?;\nDeleteUser(ctx context.Context, id int64) error\n}\n```\n\n#### Named Parameters\n\n```go\n//go:generate go run -mod=mod \"github.com/x5iu/defc\" --mode=sqlx --output=user_query.go\ntype UserQuery interface {\n// FindUsers QUERY NAMED\n// SELECT * FROM users WHERE name = :name AND age \u003e= :min_age;\nFindUsers(ctx context.Context, name string, minAge int) ([]*User, error)\n}\n```\n\n#### Const Bind Mode\n\nThe `CONSTBIND` option provides a simple way to bind Go expressions directly in SQL without template rendering overhead.\nUse `${expr}` syntax to reference variables or expressions:\n\n```go\n//go:generate go run -mod=mod \"github.com/x5iu/defc\" --mode=sqlx --output=user_query.go\ntype UserQuery interface {\n// GetUserByName QUERY CONSTBIND\n// SELECT * FROM users WHERE name = ${name} AND age \u003e ${minAge};\nGetUserByName(ctx context.Context, name string, minAge int) (*User, error)\n\n// UpdateUser EXEC CONSTBIND\n// UPDATE users SET name = ${user.Name}, age = ${user.Age} WHERE id = ${user.ID};\nUpdateUser(ctx context.Context, user *User) error\n\n// GetUsersByStatus QUERY CONSTBIND\n// SELECT * FROM users WHERE status = ${status} AND created_at \u003e ${time.Now().Add(-24 * time.Hour)};\nGetUsersByStatus(ctx context.Context, status string) ([]*User, error)\n}\n```\n\n**Key differences from other modes:**\n\n- `CONST`: SQL is used as-is, parameters must use `?` placeholders manually\n- `CONSTBIND`: SQL uses `${expr}` syntax, automatically converted to `?` placeholders with expressions as arguments\n- `BIND`: Uses Go template with `{{ bind $.var }}` syntax, rendered at runtime\n\n#### Transaction Support\n\n```go\n//go:generate go run -mod=mod \"github.com/x5iu/defc\" --mode=sqlx --output=user_query.go\ntype UserQuery interface {\nWithTx(ctx context.Context, fn func (UserQuery) error) error\n\n// CreateUser EXEC\n// INSERT INTO users (name, email) VALUES (?, ?);\nCreateUser(ctx context.Context, name, email string) error\n\n// CreateProfile EXEC\n// INSERT INTO profiles (user_id, bio) VALUES (?, ?);\nCreateProfile(ctx context.Context, userID int64, bio string) error\n}\n\n// Usage\nerr := query.WithTx(ctx, func(q UserQuery) error {\nif err := q.CreateUser(ctx, \"John\", \"john@example.com\"); err != nil {\nreturn err\n}\nreturn q.CreateProfile(ctx, userID, \"Software Developer\")\n})\n```\n\n#### Callback Support\n\nThe `sqlx/callback` and `sqlx/any-callback` features allow structs to implement callback methods that are automatically\nexecuted after query completion:\n\n```go\n//go:generate go run -mod=mod \"github.com/x5iu/defc\" --mode=sqlx --features=sqlx/callback --output=user_query.go\ntype UserQuery interface {\n// GetUser QUERY\n// SELECT id, name FROM users WHERE id = ?;\nGetUser(ctx context.Context, id int64) (*User, error)\n\n// GetUsers QUERY\n// SELECT id, name FROM users WHERE active = 1;\nGetUsers(ctx context.Context) ([]*User, error)\n}\n\ntype User struct {\nID       int64      `db:\"id\"`\nName     string     `db:\"name\"`\nProjects []*Project // Will be populated by callback\n}\n\n// Callback method for sqlx/callback feature\nfunc (u *User) Callback(ctx context.Context, query UserQuery) error {\n// Automatically called after User is populated from query\nprojects, err := query.GetProjectsByUserID(ctx, u.ID)\nif err != nil {\nreturn err\n}\nu.Projects = projects\nreturn nil\n}\n\n// For sqlx/any-callback feature (more flexible)\nfunc (u *User) Callback(ctx context.Context, executor any) error {\n// executor can be any type, providing more flexibility\nif q, ok := executor.(UserQuery); ok {\nreturn u.loadProjects(ctx, q)\n}\nreturn nil\n}\n```\n\n**Callback Features:**\n\n- `sqlx/callback`: Expects `Callback(context.Context, SpecificInterface) error`\n- `sqlx/any-callback`: Expects `Callback(context.Context, any) error` for more flexibility\n\n#### Logging Support\n\nThe `sqlx/log` feature allows you to log SQL queries and their execution details:\n\n```go\n//go:generate go run -mod=mod \"github.com/x5iu/defc\" --mode=sqlx --features=sqlx/log --output=user_query.go\ntype UserQuery interface {\n// GetUser QUERY\n// SELECT id, name FROM users WHERE id = ?;\nGetUser(ctx context.Context, id int64) (*User, error)\n}\n\n// Your database connection must implement the Log interface\ntype LoggingDB struct {\n*sqlx.DB\n}\n\nfunc (db *LoggingDB) Log(\nctx context.Context,\ncaller string, // Method name (e.g., \"GetUser\")\nquery string,         // SQL query\nargs any,             // Query arguments\nelapse time.Duration, // Execution time\n) {\nargsJSON, _ := json.Marshal(args)\nlog.Printf(\"=== %s\\nquery: %s\\nargs: %s\\nelapse: %s\\n\",\ncaller, query, string(argsJSON), elapse)\n}\n\n// Usage\ndb := \u0026LoggingDB{DB: sqlx.MustOpen(\"postgres\", dsn)}\nquery := NewUserQueryFromCore(db)\n```\n\n#### Transaction with Isolation Level\n\nThe `WithTx` method supports setting transaction isolation levels using the `ISOLATION` argument:\n\n```go\n//go:generate go run -mod=mod \"github.com/x5iu/defc\" --mode=sqlx --output=user_query.go\ntype UserQuery interface {\n// WithTx ISOLATION=sql.LevelSerializable\nWithTx(ctx context.Context, fn func (UserQuery) error) error\n\n// CreateUser EXEC\n// INSERT INTO users (name, email) VALUES (?, ?);\nCreateUser(ctx context.Context, name, email string) error\n}\n\n// Usage with serializable isolation level\nerr := query.WithTx(ctx, func(q UserQuery) error {\nreturn q.CreateUser(ctx, \"John\", \"john@example.com\")\n})\n```\n\n### HTTP Client Examples\n\n#### Basic API Client\n\n```go\ntype Config struct {\nHost   string\nAPIKey string\n}\n\ntype Response struct {\nData   any   `json:\"data\"`\nError  string `json:\"error\"`\nStatus int    `json:\"status\"`\n}\n\nfunc (r *Response) Err() error {\n// Check for API-level errors\nif r.Error != \"\" {\nreturn fmt.Errorf(\"API error: %s\", r.Error)\n}\n// Check for HTTP status errors\nif r.Status \u003e= 400 {\nreturn fmt.Errorf(\"HTTP error: status %d\", r.Status)\n}\nreturn nil\n}\n\nfunc (r *Response) ScanValues(dest ...any) error {\n// Scan response data into provided destinations\nfor _, d := range dest {\nif err := json.Unmarshal([]byte(r.Data.(string)), d); err != nil {\nreturn fmt.Errorf(\"failed to scan response data: %w\", err)\n}\n}\nreturn nil\n}\n\nfunc (r *Response) FromBytes(method string, data []byte) error {\n// Process response from raw bytes\nreturn json.Unmarshal(data, r)\n}\n\nfunc (r *Response) FromResponse(method string, resp *http.Response) error {\n// Process response from HTTP response object (default since v1.37.0)\ndefer resp.Body.Close()\ndata, err := io.ReadAll(resp.Body)\nif err != nil {\nreturn fmt.Errorf(\"failed to read response body: %w\", err)\n}\nreturn json.Unmarshal(data, r)\n}\n\nfunc (r *Response) Break() bool {\n// Control pagination: return true to stop, false to continue\n// Example: stop if no more data or reached limit\nreturn r.Data == nil || len(r.Data.([]any)) == 0\n}\n\n//go:generate go run -mod=mod \"github.com/x5iu/defc\" --mode=api --output=user_service.go\ntype UserService interface {\nOptions() *Config\nResponseHandler() *Response\n\n// CreateUser POST {{ $.Service.Host }}/api/users\n// Content-Type: application/json\n// Authorization: Bearer {{ $.Service.APIKey }}\n//\n// {\n//   \"name\": {{ $.name }},\n//   \"email\": {{ $.email }}\n// }\nCreateUser(ctx context.Context, name, email string) (*User, error)\n\n// GetUser GET {{ $.Service.Host }}/api/users/{{ $.id }}\n// Authorization: Bearer {{ $.Service.APIKey }}\nGetUser(ctx context.Context, id int64) (*User, error)\n\n// ListUsers GET MANY {{ $.Service.Host }}/api/users?page={{ page }}\n// Authorization: Bearer {{ $.Service.APIKey }}\nListUsers(ctx context.Context) ([]*User, error)\n}\n```\n\n#### Custom HTTP Client\n\n```go\n//go:generate go run -mod=mod \"github.com/x5iu/defc\" --mode=api --features=api/client --output=service.go\ntype Service interface {\nOptions() *Config\nResponseHandler() *Response\n\n// GetData GET {{ $.Service.Host }}/data\nGetData(ctx context.Context) (*Data, error)\n}\n\ntype Config struct {\nHost   string\nclient *http.Client\n}\n\nfunc (c *Config) Client() *http.Client {\nreturn c.client\n}\n\n// Usage\nconfig := \u0026Config{\nHost:   \"https://api.example.com\",\nclient: \u0026http.Client{Timeout: 30 * time.Second},\n}\nservice := NewService(config)\n```\n\n#### HTTP Request Logging\n\nThe `api/log` and `api/logx` features provide HTTP request logging capabilities:\n\n```go\n//go:generate go run -mod=mod \"github.com/x5iu/defc\" --mode=api --features=api/log --output=user_service.go\ntype UserService interface {\nOptions() *Config\nResponseHandler() *Response\n\n// GetUser GET {{ $.Service.Host }}/users/{{ $.id }}\nGetUser(ctx context.Context, id int64) (*User, error)\n}\n\n// Basic logging with api/log\ntype Config struct {\nHost string\n}\n\nfunc (c *Config) Log(\nctx context.Context,\ncaller string, // Method name (e.g., \"GetUser\")\nmethod string,        // HTTP method (e.g., \"GET\")\nurl string,           // Request URL\nelapse time.Duration, // Request duration\n) {\nlog.Printf(\"=== %s %s %s\\nelapse: %s\\n\", caller, method, url, elapse)\n}\n\n// Enhanced logging with api/logx\nfunc (c *Config) Log(\nctx context.Context,\ncaller string, // Method name\nrequest *http.Request,   // Full HTTP request\nresponse *http.Response, // Full HTTP response\nelapse time.Duration, // Request duration\n) {\nlog.Printf(\"=== %s %s %s\\nStatus: %d\\nElapse: %s\\n\",\ncaller, request.Method, request.URL.String(),\nresponse.StatusCode, elapse)\n}\n\n// Usage\nconfig := \u0026Config{Host: \"https://api.example.com\"}\nservice := NewUserService(config)\n```\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Acknowledgments\n\n- Built on top of an enhanced fork of [sqlx](https://github.com/jmoiron/sqlx) for database operations\n- Inspired by the need to reduce boilerplate code in Go applications\n- Thanks to the Go community for feedback and contributions\n- This README was generated with assistance from [Claude](https://claude.ai)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fx5iu%2Fdefc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fx5iu%2Fdefc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fx5iu%2Fdefc/lists"}