Skip to content

Commit

Permalink
feat: add code for part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
wiliamvj committed Dec 5, 2023
1 parent 5b46dd3 commit 9eb0694
Show file tree
Hide file tree
Showing 23 changed files with 871 additions and 1 deletion.
9 changes: 9 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
GO_ENV="development"
GO_PORT="8080"

POSTGRES_DB="golang_api_users"
POSTGRES_USER="golang_api_users"
POSTGRES_PASSWORD="golang_api_users"
POSTGRES_HOST="localhost"
POSTGRES_PORT="5432"
DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?sslmode=disable"
40 changes: 39 additions & 1 deletion cmd/webserver/main.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,51 @@
package main

import (
"fmt"
"log/slog"
"net/http"

"github.com/go-chi/chi"
"github.com/wiliamvj/api-users-golang/config/env"
"github.com/wiliamvj/api-users-golang/config/logger"
"github.com/wiliamvj/api-users-golang/internal/database"
"github.com/wiliamvj/api-users-golang/internal/database/sqlc"
"github.com/wiliamvj/api-users-golang/internal/handler/routes"
"github.com/wiliamvj/api-users-golang/internal/handler/userhandler"
"github.com/wiliamvj/api-users-golang/internal/repository/userrepository"
"github.com/wiliamvj/api-users-golang/internal/service/userservice"
)

func main() {
logger.InitLogger()

slog.Info("starting api")

_, err := env.LoadingConfig(".")
if err != nil {
slog.Error("failed to load environment variables", err, slog.String("package", "main"))
return
}
dbConnection, err := database.NewDBConnection()
if err != nil {
slog.Error("error to connect to database", "err", err, slog.String("package", "main"))
return
}

queries := sqlc.New(dbConnection)

// user
userRepo := userrepository.NewUserRepository(dbConnection, queries)
newUserService := userservice.NewUserService(userRepo)
newUserHandler := userhandler.NewUserHandler(newUserService)

// init routes
router := chi.NewRouter()
routes.InitUserRoutes(router, newUserHandler)

port := fmt.Sprintf(":%s", env.Env.GoPort)
slog.Info(fmt.Sprintf("server running on port %s", port))
err = http.ListenAndServe(port, router)
if err != nil {
slog.Error("error to start server", err, slog.String("package", "main"))
}
}
31 changes: 31 additions & 0 deletions config/env/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package env

import (
"github.com/spf13/viper"
)

var Env *config

type config struct {
GoEnv string `mapstructure:"GO_ENV"`
GoPort string `mapstructure:"GO_PORT"`
DatabaseURL string `mapstructure:"DATABASE_URL"`
}

func LoadingConfig(path string) (*config, error) {
viper.SetConfigFile("app_config")
viper.SetConfigType("env")
viper.AddConfigPath(path)
viper.SetConfigFile(".env")
viper.AutomaticEnv()

err := viper.ReadInConfig()
if err != nil {
return nil, err
}
err = viper.Unmarshal(&Env)
if err != nil {
return nil, err
}
return Env, nil
}
18 changes: 18 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: "3.9"

services:
postgres:
container_name: postgres_apigo
image: postgres:14.5
environment:
POSTGRES_HOST: ${POSTGRES_HOST}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_DB: ${POSTGRES_DB}
PG_DATA: /var/lib/postgresql/data
ports:
- 5432:5432
volumes:
- apigo:/var/lib/postgresql/data
volumes:
apigo:
28 changes: 28 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
module github.com/wiliamvj/api-users-golang

go 1.21.3

require (
github.com/go-chi/chi v1.5.5
github.com/lib/pq v1.10.9
github.com/spf13/viper v1.17.0
)

require (
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.10.0 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/sys v0.12.0 // indirect
golang.org/x/text v0.13.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
503 changes: 503 additions & 0 deletions go.sum

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions internal/database/connection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package database

import (
"database/sql"
"log/slog"

_ "github.com/lib/pq"
"github.com/wiliamvj/api-users-golang/config/env"
)

func NewDBConnection() (*sql.DB, error) {
postgresURI := env.Env.DatabaseURL
db, err := sql.Open("postgres", postgresURI)
if err != nil {
return nil, err
}
err = db.Ping()
if err != nil {
db.Close()
return nil, err
}
slog.Info("database connected", slog.String("package", "database"))

return db, nil
}
1 change: 1 addition & 0 deletions internal/database/migrations/000001_init.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS users;
8 changes: 8 additions & 0 deletions internal/database/migrations/000001_init.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CREATE TABLE users (
id VARCHAR(36) NOT NULL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP(3) NOT NULL
);
2 changes: 2 additions & 0 deletions internal/database/queries/users.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- name: GetUserByID :one
SELECT * from users u where u.id = $1;
31 changes: 31 additions & 0 deletions internal/database/sqlc/db.go

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

18 changes: 18 additions & 0 deletions internal/database/sqlc/models.go

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

28 changes: 28 additions & 0 deletions internal/database/sqlc/users.sql.go

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

12 changes: 12 additions & 0 deletions internal/handler/routes/user_route.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package routes

import (
"github.com/go-chi/chi"
"github.com/wiliamvj/api-users-golang/internal/handler/userhandler"
)

func InitUserRoutes(router chi.Router, h userhandler.UserHandler) {
router.Route("/user", func(r chi.Router) {
r.Post("/", h.CreateUser)
})
}
5 changes: 5 additions & 0 deletions internal/handler/userhandler/user_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package userhandler

import "net/http"

func (h *handler) CreateUser(w http.ResponseWriter, r *http.Request) {}
21 changes: 21 additions & 0 deletions internal/handler/userhandler/user_interface_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package userhandler

import (
"net/http"

"github.com/wiliamvj/api-users-golang/internal/service/userservice"
)

func NewUserHandler(service userservice.UserService) UserHandler {
return &handler{
service,
}
}

type handler struct {
service userservice.UserService
}

type UserHandler interface {
CreateUser(w http.ResponseWriter, r *http.Request)
}
23 changes: 23 additions & 0 deletions internal/repository/userrepository/user_interface_repository.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package userrepository

import (
"database/sql"

"github.com/wiliamvj/api-users-golang/internal/database/sqlc"
)

func NewUserRepository(db *sql.DB, q *sqlc.Queries) UserRepository {
return &repository{
db,
q,
}
}

type repository struct {
db *sql.DB
queries *sqlc.Queries
}

type UserRepository interface {
CreateUser() error
}
5 changes: 5 additions & 0 deletions internal/repository/userrepository/user_repository.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package userrepository

func (r *repository) CreateUser() error {
return nil
}
17 changes: 17 additions & 0 deletions internal/service/userservice/user_interface_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package userservice

import "github.com/wiliamvj/api-users-golang/internal/repository/userrepository"

func NewUserService(repo userrepository.UserRepository) UserService {
return &service{
repo,
}
}

type service struct {
repo userrepository.UserRepository
}

type UserService interface {
CreateUser() error
}
5 changes: 5 additions & 0 deletions internal/service/userservice/user_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package userservice

func (s *service) CreateUser() error {
return nil
}
12 changes: 12 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
include .env

create_migration:
migrate create -ext=sql -dir=internal/database/migrations -seq init

migrate_up:
migrate -path=internal/database/migrations -database "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?sslmode=disable" -verbose up

migrate_down:
migrate -path=internal/database/migrations -database "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?sslmode=disable" -verbose down

.PHONY: create_migration migrate_up migrate_down
Loading

0 comments on commit 9eb0694

Please sign in to comment.