https://github.com/mmoehabb/goweb-template
A template for developing full-stack web applications in Go.
https://github.com/mmoehabb/goweb-template
fullstack-web-development golang template
Last synced: 22 days ago
JSON representation
A template for developing full-stack web applications in Go.
- Host: GitHub
- URL: https://github.com/mmoehabb/goweb-template
- Owner: mmoehabb
- License: mit
- Created: 2024-09-02T03:52:04.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-02-05T03:32:40.000Z (over 1 year ago)
- Last Synced: 2025-05-07T03:08:26.889Z (about 1 year ago)
- Topics: fullstack-web-development, golang, template
- Language: Go
- Homepage:
- Size: 2.3 MB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
A template for developing full-stack web applications in Golang.

## Used Technologies
- [Golang](https://go.dev/)
- [Templ](https://templ.guide/)
- [TemplUI](https://templui.io/)
- [Tailwind](https://tailwindcss.com/)
- [HTMX](https://htmx.org/)
- [Fiber](https://docs.gofiber.io/)
- [Postgres](https://github.com/jackc/pgx)
- [Goose](https://github.com/pressly/goose) (Database Migrations)
## Template Structure
### root files
#### main.go
As you probably know `main.go` is the starting point of your go application. In this template, it merely initializes a fiber app, adds some middlewares, and defines a couple of endpoints.
#### luci.config.toml
Just an extra tool used as a shorthand for commands, as shown [below](#luci-cli). You can just delete it, if you don't like it!
### handlers
This package (directory) includes all fiber callback functions, used in `main.go`, aggregated or grouped into different packages (directories). And for each sub-package there should exist two files: `types.go` and `validators.go`; the first defines related types to the group (i.e. User, Credentials...etc), whereas the latter defines different validate functions to be used in handlers while getting users inputs (requests payloads).
### db
This package exports functions related to the database, and more importantly it has sub-packages with a more specified functions for various (system) entities.
It exports two functions and a struct. The function `Queries` acquires a connection then executes the supplied sql query (a string parameter), then returns the result as a slice of type `[]any`, and finally releases the connection. The `GetConnection` function, on the other hand, initializes and returns a `Connection` struct that can be used by users to order to send sequential queries with the same db client connection.
> before v0.0.4: "The exported functions are: Query, SeqQuery, Queries, and Disconnect. `Query` function establishes a connection then executes the supplied sql query (a string parameter), then returns the result as a slice of type `[]any`, and finally closes the connection. `SeqQuery` is just like `Query` however it doesn't close the connection eventually; so make sure to call `Disconnect` after a series (sequence) of `SeqQuery` calls. And lastly, `Queries` just takes a slice of strings parameter rather than a single string, executes each sql query, closes the connection, and then returns nil or error in case an error occured".
db package constitutes of several sub-packages each of which declares and defines various db functions, related to a specific entity, by using the above-mentioned functions/utilities. For example, the `db/user` package exports `Add` and `Get` functions that can be used directly by [handlers](#handlers) to communicate with the database.
### public
Public assests live in the `./public` directory, which is served by the file server of fiber by using the method: `app.Static(...)` in `main.go`. You should put here all the pictures, videos, sound, scripts...etc, that shall be publicly served to all users with no restrictions.
### pages & ui
These two packages contain only '.templ' files. As the name indicates, the first is for the application pages: templ components with '' and '' tag names. The latter, on the other hand, constitutes of several sub-packages for several ui categories, like: forms, components, layouts, mini-components...etc.
### ancillaries
This package shall contain all logic that's shared between other packages and sub-packages.
### constants
All constant values shall be defined in this package. For example, your `.env` file values are represented in this package as a global go struct that can be imported from anywhere else.
### Directory Tree
```
.
├── luci.config.toml
├── go.mod
├── go.sum
├── .templui.json
├── LICENSE
├── main.go
├── README.md
├── ancillaries
│ └── errors.go
├── components
│ └── button
│ └── button.templ
├── constants
│ └── config.go
├── db
│ ├── db.go
│ ├── migrations/
│ │ └── 001_create_users.sql
│ └── user
│ └── queries.go
├── handlers
│ └── user
│ ├── login.go
│ ├── register.go
│ ├── types.go
│ └── validators.go
├── pages
│ └── index.templ
├── public
│ ├── globals.css
│ ├── tailwind.js
│ ├── util.js
│ └── ...
├── ui
│ ├── components
│ │ ├── Button.templ
│ │ └── TextInput.templ
│ ├── forms
│ │ ├── login.templ
│ │ └── register.templ
│ └── layouts
│ ├── footer.templ
│ └── header.templ
└── utils
└── templui.go
```
## Usage
Download the source code or just clone this repository and delete .git directory:
```shell
$ git clone https://github.com/mmoehabb/goweb-template
$ rm -rf .git
$ git init # optional
```
> Make sure you have installed [go](https://go.dev/doc/install) and [templ](https://templ.guide/quick-start/installation):
Install the dependencies with; execute the following command on the root directory:
```shell
$ go install
```
> You may use `luci install`, as mentioned below in "Luci CLI" section, to install both the packages and the tools (templ and air binaries) all at once.
Then, write the following command to compile templ files and run the server afterwards:
```shell
$ templ generate --cmd "go run ."
```
If everything went right, you should be able to see the template live on [http://localhost:3000](http://localhost:3000)
You can also enable live reload with the command:
```shell
$ templ generate --watch --cmd "go run ."
```
However this will watch only templ files, you may wanna reload the server when go files are modified as well.
For this sake `.air.toml` file (as you may have noticed) is in the root directory; make sure to install [air](https://github.com/air-verse/air) then execute the previous command with `air` instead of `go run .`.
```shell
$ templ generate --watch --cmd "air"
```
### Play the Game
In order to see all the template functionalities in action, you have to make sure that a postgresql service is running on your machine with a 'postgres' database created, or any (postgres) database you already have but make sure to modify the database connection config in `db/db.go` file accordingly:
> If you just wanna PLAY THE GAME without all this crap; just call `start()` function in the developer tools.
```Golang
// You will find this line in `connect` function in `db.go`.
conn, err = pgx.Connect(context.Background(), "postgres://postgres:postgres@localhost:5432/postgres")
```
If you haven't established a postgresql server before, you may find the following steps helpful:
1. Download & install postgres from here: [https://www.postgresql.org/download/](https://www.postgresql.org/download/)
2. Modify `pg_hba.conf` to enable md5 remote access:
- specify user to "postgres": `$ su - postgres`
- run the following command in order to find the coniguration file location: `$ psql -c "SHOW config_file"`
- open the file `pg_hba.conf` located at the same directory of `postgresql.conf`, then add the lines, shown below step 3, to the end of it:
3. Start the service:
```shell
$ service postgresql start
```
```
# Add these lines to the end of pg_hba.conf
# This means that remote access is allowed using IP v4 and IP v6 to all databases and all users using the "md5" authentication protocol
host all all 127.0.0.1/0 md5
host all all ::/0 md5
```
And finally run the application, register, login, and have fun:
```shell
$ go run .
```
### Database Migrations
This template uses [Goose](https://github.com/pressly/goose) for database migrations. Migrations run automatically when the application starts.
#### Migration Files
Migration files are stored in `db/migrations/` with SQL files named with a timestamp prefix:
```
db/migrations/
└── 001_create_users.sql
```
#### CLI Commands
You can also run migrations manually using the goose CLI:
```shell
# Install goose
go install github.com/pressly/goose/v3/cmd/goose@latest
# Run migrations (specify migrations directory with -dir)
goose postgres "postgres://user:pass@localhost:5432/db?sslmode=disable" up -dir ./db/migrations
# Rollback last migration
goose postgres "postgres://user:pass@localhost:5432/db?sslmode=disable" down -dir ./db/migrations
# Check status
goose postgres "postgres://user:pass@localhost:5432/db?sslmode=disable" status -dir ./db/migrations
# Create new migration
goose create add_new_table sql -dir ./db/migrations
```
Or use luci shorthand commands (configured in `luci.config.toml`):
```shell
luci bash.migrate status # Check migration status
luci bash.migrate up # Run pending migrations
luci bash.migrate down # Rollback last migration
```
#### Creating New Migrations
```sql
-- db/migrations/002_add_users_email.sql
-- +goose Up
-- +goose StatementBegin
CREATE TABLE IF NOT EXISTS users (
username VARCHAR(45) PRIMARY KEY,
password VARCHAR(45) NOT NULL,
email VARCHAR(255) UNIQUE
);
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
ALTER TABLE users DROP COLUMN email;
-- +goose StatementEnd
```
### Luci CLI
You may use the [luci](https://github.com/mmoehabb/luci) CLI tool, as a shorthand for the above-mentioned commands:
```shell
$ go install github.com/mmoehabb/luci@latest
$ luci dev # executes: "templ generate --watch --cmd 'air'"
```