Skip to content

Commit

Permalink
go-api: Postgres & sqlc (#80)
Browse files Browse the repository at this point in the history
* go-api: Postgres & sqlc

* linting

* linting

* refactor: first refactor of the project including ai suggestions

* refactor: add layers to separate logic

* fix: format issues in .gitignore and dockerfile

* fix: add password hashing

* fix: error response header

* fix: NewText return

* fix: add .sqlfluff file

* fix: error handling in db conn

---------

Co-authored-by: Chelo Doz <[email protected]>
  • Loading branch information
darioscrivano and chelodoz authored Jun 10, 2024
1 parent bdb51d8 commit cf44a24
Show file tree
Hide file tree
Showing 20 changed files with 803 additions and 0 deletions.
22 changes: 22 additions & 0 deletions examples/golang-api-with-postgres-and-sqlc/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

# Go workspace file
go.work
go.work.sum
2 changes: 2 additions & 0 deletions examples/golang-api-with-postgres-and-sqlc/.sqlfluff
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[sqlfluff]
dialect = postgres
26 changes: 26 additions & 0 deletions examples/golang-api-with-postgres-and-sqlc/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Build stage
FROM golang:1.22 AS builder

WORKDIR /go/src/app

# Pre-copy/cache go.mod and go.sum for pre-downloading dependencies
COPY go.mod go.sum ./
RUN go mod download

# Copy the source code
COPY . .

# Build the Go application
RUN go build -v -o /go/bin/app .

# Final stage
FROM gcr.io/distroless/base-debian12:latest

# Copy the compiled binary from the build stage
COPY --from=builder /go/bin/app /

# Expose the application port
EXPOSE 8080

# Set the command to run the application
CMD ["/app"]
56 changes: 56 additions & 0 deletions examples/golang-api-with-postgres-and-sqlc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Go API with Docker Compose

This project containerizes a Go API and a PostgreSQL database using Docker Compose.

## Motivation for Using `sqlc`

Incorporating `sqlc` into a Go project provides numerous advantages:

- **Strong Type Safety**: Compile-time checks ensure that type errors are caught early in the development process, reducing runtime errors and increasing code reliability.
- **Enhanced Developer Productivity**: By automating the generation of SQL queries and their corresponding Go code, `sqlc` allows developers to concentrate on building application features instead of writing boilerplate database interaction code.
- **Improved Readability and Maintainability**: Using native SQL queries directly in the codebase makes the queries more transparent and easier to understand, debug, and optimize. This approach aligns well with the principles of clean code and maintainability.
- **Optimized Performance**: `sqlc` enables developers to write and fine-tune raw SQL queries, providing greater control over database interactions compared to ORM-based solutions. This can lead to more efficient query execution and better overall performance.

## Prerequisites

- Docker
- Docker Compose
- `sqlc`

## Setup

1. **Clone the Repository**:

```bash
git clone https://github.com/nanlabs/backend-reference
```

2. **Navigate to the Project Directory**:

```bash
cd backend-reference/examples/golang-api-with-postgres-and-sqlc
```

3. **Generate SQL Queries and Models with `sqlc`**:

```bash
sqlc generate
```

4. **Build and Run the Docker Containers**:

```bash
docker-compose build
docker-compose up
```

The Go API will be accessible at `localhost:8080`.

## Stopping the Application

To stop the application and remove the containers, networks, and volumes defined in `docker-compose.yml`, run:

```bash
docker-compose down
docker volume rm db_data
```
23 changes: 23 additions & 0 deletions examples/golang-api-with-postgres-and-sqlc/compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: "3"
services:
db:
container_name: db
image: postgres:16
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: poc
volumes:
- db_data:/var/lib/postgresql/data
ports:
- "5432:5432"
go_api:
container_name: go_api
build: .
depends_on:
- db
ports:
- "8080:8080"
volumes:
db_data:
name: db_data
37 changes: 37 additions & 0 deletions examples/golang-api-with-postgres-and-sqlc/db/database.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package db

import (
"context"
"fmt"
"go-postgres-sqlc/db/sqlc"
"log"

"github.com/jackc/pgx/v5"
)

// DB holds the database connection configuration
type DB struct {
DSN string
Context context.Context
Conn *pgx.Conn
Queries *sqlc.Queries
}

// New initializes a new DBConfig instance
func New(dsn string) (*DB, error) {
ctx := context.Background()
conn, err := pgx.Connect(ctx, dsn)
if err != nil {
return nil, fmt.Errorf("unable to connect to database: %v", err)
}
log.Println("Connected to database")

queries := sqlc.New(conn)

return &DB{
DSN: dsn,
Context: ctx,
Conn: conn,
Queries: queries,
}, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE users (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
username VARCHAR(30) NOT NULL,
password VARCHAR(100) NOT NULL,
email VARCHAR(50),
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);
29 changes: 29 additions & 0 deletions examples/golang-api-with-postgres-and-sqlc/db/query/user.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-- name: GetUser :one
SELECT
id,
username,
email,
created_at
FROM users
WHERE id = @user_id
LIMIT 1;

-- name: ListUsers :many
SELECT
id,
username,
email,
created_at
FROM users
ORDER BY username;

-- name: CreateUser :one
INSERT INTO users (
username,
password,
email
) VALUES (
@username,
@password,
@email
) RETURNING *;
32 changes: 32 additions & 0 deletions examples/golang-api-with-postgres-and-sqlc/db/sqlc/db.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions examples/golang-api-with-postgres-and-sqlc/db/sqlc/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions examples/golang-api-with-postgres-and-sqlc/db/sqlc/querier.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

116 changes: 116 additions & 0 deletions examples/golang-api-with-postgres-and-sqlc/db/sqlc/user.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit cf44a24

Please sign in to comment.