Compare commits

..

No commits in common. "master" and "feature/post-request" have entirely different histories.

17 changed files with 121 additions and 229 deletions

1
.env
View file

@ -1 +0,0 @@
COMPOSE_PROJECT_NAME=genitywebapp

3
.gitignore vendored
View file

@ -15,9 +15,6 @@
# Dependency directories (remove the comment below to include it)
# vendor/
# Output directories
bins/
# ---> macOS
# General
.DS_Store

8
Dockerfile Normal file
View file

@ -0,0 +1,8 @@
FROM golang:alpine as builder
RUN mkdir -p /go/src/app
WORKDIR /go/src/app
ADD . /go/src/app
RUN go get -d -v

View file

@ -1,14 +0,0 @@
build:
docker-compose build
up: build
docker-compose up
build-binary:
go mod download
GOOS=linux GOARCH=amd64 go build -o bins/genityapp -v cmd/*
run: build-binary up
.PHONY: build-binary run build up

View file

@ -1,15 +1,6 @@
#How to run this project
##Navigate to root of project, run following command
`make run`
###API interfacing
* Get request
`curl http://localhost:5000/get-data?title=shahzad`
* Post request
`curl --request POST 'http://localhost:5000/post-data' --data "title=shahzad"`
Just basic golang and postgres docker poc.
To build docker compose
`docker-compose up --build`
@ -19,6 +10,6 @@ To run docker compose
To connect with psql using following command
`docker exec -it genitywebapp_db_1 psql -U root_user -W db_genity`
`docker exec -it poc-golang-postgres-docker_db_1 psql -U root_user -W db_genity`

View file

@ -1,9 +1,8 @@
package app
package main
import (
"encoding/json"
"fmt"
uuid "github.com/nu7hatch/gouuid"
"net/http"
"time"
)
@ -12,81 +11,53 @@ type User struct {
UserID int
Title string
CreatedOn time.Time
Uuid string
}
type Users struct {
users []User
}
/**
Sample request http://localhost:5000/get-data?title=shahzad
*/
func UserGetHandler(w http.ResponseWriter, req *http.Request) {
if req.Method == "GET" {
users := Users{}
title, ok := req.URL.Query()["title"]
if !ok || len(title[0]) < 1 {
http.Error(w, "Url Param 'title' is missing", 400)
return
}
// Query()["key"] will return an array of items,
// we only want the single item.
userTitle := title[0]
usersData := Users{}
err := queryRepos(&usersData, userTitle)
err := queryRepos(&users)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
if len(usersData.users) > 0 {
out, err := json.Marshal(usersData.users)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
fmt.Fprintf(w, string(out))
} else {
fmt.Fprintf(w, "User does not exist")
out, err := json.Marshal(users.users)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
fmt.Fprintf(w, string(out))
} else {
fmt.Fprintf(w, "Sorry, only Get methods are supported for thus api.")
}
}
/**
Sample request curl --request POST 'http://localhost:5000/post-data' --data "title=shahzad"
*/
func UserPostHandler(w http.ResponseWriter, req *http.Request) {
if req.Method == "POST" {
if err := req.ParseForm(); err != nil {
fmt.Fprintf(w, "ParseForm() err: %v", err)
return
}
uuid, err := uuid.NewV4()
if err != nil {
http.Error(w, err.Error(), 500)
}
title := req.FormValue("title")
sqlInsert := `
INSERT INTO users (title, created_on)
VALUES ($1, $2)
RETURNING user_id`
if len(title) > 0 {
user_id := 0
row := Db.QueryRow(SqlPostUser, title, time.Now().Format(time.RFC3339), uuid.String())
row := db.QueryRow(sqlInsert, title, time.Now())
err := row.Scan(&user_id)
if err != nil {
fmt.Fprintf(w, err.Error())
panic(err)
}
fmt.Fprintf(w, `title=`+title)
fmt.Fprintf(w, "user creted")
} else {
fmt.Fprintf(w, "Invalid data")
}
@ -95,9 +66,15 @@ func UserPostHandler(w http.ResponseWriter, req *http.Request) {
}
}
func queryRepos(users *Users, userTitle string) error {
rows, err := Db.Query(SqlGetUser, userTitle)
func queryRepos(users *Users) error {
rows, err := db.Query(`
SELECT
user_id,
title,
created_on
FROM users;
`)
if err != nil {
return err
}
@ -108,7 +85,6 @@ func queryRepos(users *Users, userTitle string) error {
&user.UserID,
&user.Title,
&user.CreatedOn,
&user.Uuid,
)
if err != nil {
return err

View file

@ -1,8 +0,0 @@
FROM golang:alpine as builder
ADD bins/genityapp /etc/local/genityapp
WORKDIR /etc/local/
ENTRYPOINT ["./genityapp"]

View file

@ -1,22 +0,0 @@
package main
import (
"domain/genityapp/internal/app"
"fmt"
_ "github.com/lib/pq"
"log"
"net/http"
)
func main() {
app.InitDb()
defer app.CloseDB()
http.HandleFunc("/get-data", app.UserGetHandler)
http.HandleFunc("/post-data", app.UserPostHandler)
fmt.Println("Listening on :5000")
log.Fatal(http.ListenAndServe(":5000", nil))
}

View file

@ -1,3 +0,0 @@
POSTGRES_DB=db_genity
POSTGRES_USER=root_user
POSTGRES_PASSWORD=shahzad12

View file

@ -1,5 +0,0 @@
dbhost=genitywebapp_db_1
dbport=5432
dbuser=root_user
dbpass=shahzad12
dbname=db_genity

4
db_dump Normal file
View file

@ -0,0 +1,4 @@
CREATE TABLE users ( user_id serial PRIMARY KEY, title VARCHAR ( 50 ) UNIQUE NOT NULL, created_on TIMESTAMP NOT NULL);
INSERT INTO users (title,created_on) VALUES('shahzad','2013-06-01');

View file

@ -1,33 +1,30 @@
version: "3"
version: '3'
services:
db:
image: postgres
env_file: ./configs/db.env
environment:
POSTGRES_DB: db_genity
POSTGRES_USER: root_user
POSTGRES_PASSWORD: shahzad12
volumes:
- db_postgres:/var/lib/postgresql/data
- ./scripts/db/ddl_01.sql:/docker-entrypoint-initdb.d/10_schema.sql
- ./scripts/db/dml_01.sql:/docker-entrypoint-initdb.d/20_insert.sql
expose:
- "5432"
restart: always
networks:
- genityapp_network
web:
build:
context: .
dockerfile: build/Dockerfile
env_file: ./configs/web.env
ports:
- "5000:5000"
restart: always
- "5436:5432"
networks:
- genity_network
app:
build: ""
command: [ "go", "run", "main.go","api.go"]
ports:
- "8080:8080"
depends_on:
- db
links:
- db
networks:
- genityapp_network
- genity_network
volumes:
db_postgres:
networks:
genityapp_network:
genity_network:
driver: bridge

3
go.mod
View file

@ -1,8 +1,7 @@
module domain/genityapp
module genity-code-review
go 1.14
require (
github.com/lib/pq v1.8.0
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d
)

View file

@ -1,90 +0,0 @@
package app
import (
"database/sql"
"fmt"
"os"
)
const (
dbhost = "dbhost"
dbport = "dbport"
dbuser = "dbuser"
dbpass = "dbpass"
dbname = "dbname"
)
const (
SqlGetUser = `
SELECT
user_id,
title,
created_on,
uuid
FROM users
WHERE title=$1;
`
SqlPostUser = `
INSERT INTO users (title, created_on,uuid)
VALUES ($1, $2, $3)
RETURNING user_id`
)
var Db *sql.DB
func InitDb() {
config := dbConfig()
var err error
psqlInfo := fmt.Sprintf("postgres://%v:%v@%v:%v/%v?sslmode=disable",
config[dbuser], config[dbpass],
config[dbhost], config[dbport], config[dbname])
fmt.Println(psqlInfo)
Db, err = sql.Open("postgres", psqlInfo)
if err != nil {
panic(err)
}
err = Db.Ping()
if err != nil {
panic(err)
}
fmt.Println("Successfully connected!")
}
func CloseDB() {
Db.Close()
}
func dbConfig() map[string]string {
conf := make(map[string]string)
host, ok := os.LookupEnv(dbhost)
if !ok {
panic("DBHOST environment variable required but not set")
}
port, ok := os.LookupEnv(dbport)
if !ok {
panic("DBPORT environment variable required but not set")
}
user, ok := os.LookupEnv(dbuser)
if !ok {
panic("DBUSER environment variable required but not set")
}
password, ok := os.LookupEnv(dbpass)
if !ok {
panic("DBPASS environment variable required but not set")
}
name, ok := os.LookupEnv(dbname)
if !ok {
panic("DBNAME environment variable required but not set")
}
conf[dbhost] = host
conf[dbport] = port
conf[dbuser] = user
conf[dbpass] = password
conf[dbname] = name
return conf
}

66
main.go Normal file
View file

@ -0,0 +1,66 @@
package main
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
"log"
"net/http"
)
var db *sql.DB
const (
dbhost = "DBHOST"
dbport = "DBPORT"
dbuser = "DBUSER"
dbpass = "DBPASS"
dbname = "DBNAME"
)
func main() {
initDb()
defer db.Close()
http.HandleFunc("/api/users", UserGetHandler)
http.HandleFunc("/api/user", UserPostHandler)
fmt.Println("Listening on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func initDb() {
config := dbConfig()
var err error
psqlInfo := fmt.Sprintf("postgres://%v:%v@%v:%v/%v?sslmode=disable",
config[dbuser], config[dbpass],
config[dbhost], config[dbport], config[dbname])
fmt.Println(psqlInfo)
db, err = sql.Open("postgres", psqlInfo)
if err != nil {
panic(err)
}
err = db.Ping()
if err != nil {
panic(err)
}
fmt.Println("Successfully connected!")
}
func dbConfig() map[string]string {
conf := make(map[string]string)
conf[dbhost] = "poc-golang-postgres-docker_db_1"
conf[dbport] = "5432"
conf[dbuser] = "root_user"
conf[dbpass] = "shahzad12"
conf[dbname] = "db_genity"
return conf
}

View file

@ -1,2 +0,0 @@
CREATE TABLE users (user_id serial PRIMARY KEY, title VARCHAR ( 50 ) UNIQUE NOT NULL,
uuid VARCHAR ( 50 ) UNIQUE NOT NULL, created_on TIMESTAMP NOT NULL);

View file

@ -1 +0,0 @@
INSERT INTO users (title,created_on, uuid) VALUES('shahzad','2013-06-01', '8272-28292-287292');