Skip to content

behzade/go-template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

50 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go Template

Go template project with echo and mysql This project is a template for building web applications using Go, echo, and MySQL. It provides a dockerized environment, a config system, a database schema management and code gen from database schema and openapi specification.

Table of Contents

Getting Started

  1. Clone the project and navigate to the root directory.
  2. Run make build to build the containers needed to run the project.
  3. Run make up to start the containers.
  4. Visit http://localhost:8080 to see the application running.

Project Structure

Docker

The project runtime is dockerized in two different docker files. Dockerfile.dev for developement with live reload and Dockerfile that is intended to be the production container definition. The docker and compose are stored in the docker directory.

Docker Registry

You can override the default docker registry by adding the following value to docker/.env

DOCKER_REGISTRY=<your-docker-registry>

This might be necessary if you are behind a firewall that can access the default registry.

Config

Project config is stored in the config.yaml at the root of the project. This file is read by the config.go and all the values can be overriden using environment variables. Any missing value from the env variables is read from yaml file by default. Example:

	Database struct {
		Host string `yaml:"host" envconfig:"DB_HOST"`
		Port int    `yaml:"port" envconfig:"DB_PORT"`
		Name string `yaml:"name" envconfig:"DB_NAME"`
		User string `yaml:"user" envconfig:"DB_USER"`
		Pass string `yaml:"pass" envconfig:"DB_PASS"`
	} `yaml:"database"`

Env Variables

You can override the local config with env variables by adding the file docker/.env.

Database

Schema

Database schema is stored in the schema.sql file in the sql/schema directory. You can put your partial templates in the same directory. The template is rendered to a single sql file which represents the desired database state. Schema template example with partial templates:

{{define "id"}}`id` bigint unsigned not null auto_increment{{end}}
{{define "createdAt"}}`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP{{end}}
{{define "updatedAt"}}`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP{{end}}

create database {{.schema}};

create table {{.schema}}.user (
    {{template "id"}},
    `name` varchar(255) not null,
    {{template "createdAt"}},
    {{template "updatedAt"}},
    PRIMARY KEY(`id`)
);
Altering the Schema

To change the database schema, first make your changes to the template file and then run the make get_alters to get the db alters that need to be ran. You can run the alters using the make apply_alters on the local database. On production env this will be handled in a CI/CD stage. We use the atlasgo to diff/apply the schema. Let's add an age column to our user table:

create table {{.schema}}.user (
    {{template "id"}},
    `name` varchar(255) not null,
    `age` int null,
    {{template "createdAt"}},
    {{template "updatedAt"}},
    PRIMARY KEY(`id`)
);

Now we should run make get_alters to see the changes database.

Pending Alters:
ALTER TABLE `localdb`.`user` ADD COLUMN `age` int NULL

And make sync_entity to update the generated go code in entity package:

type LocaldbUser struct {
	ID        uint64
	Name      string
	Age       sql.NullInt32
	CreatedAt time.Time
	UpdatedAt time.Time
}

API

api dir holds the openapi specification and the code gen config for oapi-codegen. To generate the server interface from specification use make api. This generates/updates internal/controller/api.go file.

Packages

Entity

entity is the package of generated go code from the sql/schema and sql/query files. This package is generated by sqlc and is the primary way of interacting with database in the application code. Example sql query:

-- name: GetUser :one
select * from localdb.user where id = ?;

Generated go code:

func (q *Queries) GetUser(ctx context.Context, id uint64) (LocaldbUser, error) {
	row := q.db.QueryRowContext(ctx, getUser, id)
	var i LocaldbUser
	err := row.Scan(
		&i.ID,
		&i.Name,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

Keep in mind that this package needs to be regenerated after making changes to schema/query using make sync_entity.

Controller

echo is the router of choice for this project. Routes are generated from the openapi specification in ./api/service.yaml. To use, simply implement the ServerInterface or StrictServerInterface for your specification.

Service

service package is responsible for handling config init and database connections and monitoring tools.

About

Go project template

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published