Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix gorm, swagger. Add infra components #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 0 additions & 26 deletions .env

This file was deleted.

27 changes: 20 additions & 7 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
BASE_URL=127.0.0.1
API_PORT=443
API_PORT=8000

PROJECT_NAME=gotham
PROJECT_HOST=localhost
PROJECT_URL=https://www.example.com
PROJECT_API_URL=https://api.example.com

#DB
DB_CONNECTION=mysql
DB_DATABASE=example
DB_CONNECTION=postgres
DB_USERNAME=gotham
DB_DATABASE=gotham
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=admin
DB_PASSWORD=admin
DB_PORT=35432
DB_PASSWORD=password

PGUSER=admin
PGPASSWORD=password
PGDATABASE=gotham
PGHOST=localhost
PGPORT=35432

#EMAIL
[email protected]
HOST=smtp.gmail.com
PORT=587
PASSWORD=password

#VERSION
VERSION=0.1

#JWT_SECRET_KEY
JWT_SECRET_KEY=7l6dds5z2egrfcw01s6e78arte48067
JWT_SECRET_KEY=jwt_secret_key
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@
# vendor/


*.idea
*.idea

.env
27 changes: 27 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# vim: set noet ci pi sts=0 sw=4 ts=4 :
# http://www.gnu.org/software/make/manual/make.html
# http://linuxlib.ru/prog/make_379_manual.html
SHELL := $(shell which bash)
#SHELL := $(shell which sh)
DEBUG ?= 0

########################################################################
# Default variables
########################################################################
-include .env
export
########################################################################
GOBIN := $(or $(GOBIN), $(GOPATH)/bin)
SUDO := $(or $(SUDO),)
GO111MODULE := $(or $(GO111MODULE), on)
GOROOT := $(GOPATH/src)
TAGS :=
LDFLAGS := -w -s
GOFLAGS :=

.PHONY: db-init
db-init:
set -o allexport;
source .env;
set +o allexport;
./infra/db/$(DB_CONNECTION)_init.sh
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,21 @@ DB_PORT=3306
DB_PASSWORD=strong_password
```

## Infra

```
cp .env.example .env

docker-compose up -d
# wait for pg container is up
# login from pgadmin and check database status

make db-init

go install github.com/swaggo/swag/cmd/[email protected]
swag init -g main.go
```

## Flags

- prevents re-creating container methods from definitions
Expand Down Expand Up @@ -115,6 +130,20 @@ go run gotham -seed

### ViewModels
ViewModels folder hosts all the structs under viewmodels namespace, viewmodels are model to be use as a response return of REST API call

## Test

```
set -o allexport;
source .env;
set +o allexport;
export ADMIN_EMAIL=$(echo "SELECT json_agg(users) FROM users WHERE id=1" |psql -AXqt | jq -r '.[].email')
export ADMIN_TOKEN=$(curl -s -X POST "http://${BASE_URL}:${API_PORT}/v1/login" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"email\": \"${ADMIN_EMAIL}\", \"password\": \"password\", \"platform\": \"web\"}" | jq -r .data.access_token)

curl -X GET "http://${BASE_URL}:${API_PORT}/v1/r/users" -H "accept: application/json" -H "Authorization: Bearer ${ADMIN_TOKEN}"
curl -X GET "http://${BASE_URL}:${API_PORT}/v1/r/users/2" -H "accept: application/json" -H "Authorization: Bearer ${ADMIN_TOKEN}"
```


## Author

Expand All @@ -139,4 +168,4 @@ Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
6 changes: 3 additions & 3 deletions app/container/dic/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import (
// The function panics if the Container can not be retrieved.
//
// The interface can be :
// - a *Container
// - an *http.Request containing a *Container in its context.Context
// for the dingo.ContainerKey("dingo") key.
// - a *Container
// - an *http.Request containing a *Container in its context.Context
// for the dingo.ContainerKey("dingo") key.
//
// The function can be changed to match the needs of your application.
var C = func(i interface{}) *Container {
Expand Down
9 changes: 8 additions & 1 deletion config/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Config struct {
Brand struct {
ProjectName string
ProjectUrl string
ProjectHost string
ProjectApiUrl string
}
}
Expand All @@ -47,7 +48,13 @@ func Configurations() {
Brand: struct {
ProjectName string
ProjectUrl string
ProjectHost string
ProjectApiUrl string
}{ProjectName: os.Getenv("PROJECT_NAME"), ProjectUrl: os.Getenv("PROJECT_URL"), ProjectApiUrl: os.Getenv("PROJECT_API_URL")},
}{
ProjectName: os.Getenv("PROJECT_NAME"),
ProjectUrl: os.Getenv("PROJECT_URL"),
ProjectHost: os.Getenv("PROJECT_HOST"),
ProjectApiUrl: os.Getenv("PROJECT_API_URL"),
},
}
}
7 changes: 4 additions & 3 deletions controllers/userController.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type UserController struct {
// @Accept multipart/form-data
// @Accept application/x-www-form-urlencoded
// @Produce json
// @Param token header string true "Bearer Token"
// @Param Authorization header string true "Bearer Token"
// @Success 200 {object} viewModels.Paginator{data=[]models.User}
// @Failure 400 {object} viewModels.Message{}
// @Failure 401 {object} viewModels.Message{}
Expand Down Expand Up @@ -70,14 +70,15 @@ func (u UserController) Index(c echo.Context) (err error) {
// @Accept multipart/form-data
// @Accept application/x-www-form-urlencoded
// @Produce json
// @Param token header string true "Bearer Token"
// @Param user path string true "1"
// @Param Authorization header string true "Bearer Token"
// @Success 200 {object} viewModels.HTTPSuccessResponse{data=models.User}
// @Failure 404 {object} viewModels.Message{}
// @Failure 401 {object} viewModels.Message{}
// @Failure 400 {object} viewModels.Message{}
// @Failure 403 {object} viewModels.Message{}
// @Failure 500 {object} viewModels.Message{}
// @Router /v1/r/users/:user [get]
// @Router /v1/r/users/{user} [get]
func (u UserController) Show(c echo.Context) (err error) {
auth := models.ConvertUser(c.Get("auth"))

Expand Down
22 changes: 22 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
version: '3.8'

services:
pg:
image: postgres:13.3
container_name: gotham_pg
restart: always
environment:
POSTGRES_PASSWORD: "password"
POSTGRES_USER: "admin"
ports:
- '35432:5432'


pgadmin:
image: dpage/pgadmin4:latest
container_name: gotham_pgadmin
environment:
PGADMIN_DEFAULT_EMAIL: "[email protected]"
PGADMIN_DEFAULT_PASSWORD: "password"
ports:
- '32082:80'
13 changes: 10 additions & 3 deletions docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ var doc = `{
{
"type": "string",
"description": "Bearer Token",
"name": "token",
"name": "Authorization",
"in": "header",
"required": true
}
Expand Down Expand Up @@ -212,7 +212,7 @@ var doc = `{
}
}
},
"/v1/r/users/:user": {
"/v1/r/users/{user}": {
"get": {
"consumes": [
"application/json",
Expand All @@ -227,10 +227,17 @@ var doc = `{
],
"summary": "Get User",
"parameters": [
{
"type": "string",
"description": "1",
"name": "user",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Bearer Token",
"name": "token",
"name": "Authorization",
"in": "header",
"required": true
}
Expand Down
13 changes: 10 additions & 3 deletions docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
{
"type": "string",
"description": "Bearer Token",
"name": "token",
"name": "Authorization",
"in": "header",
"required": true
}
Expand Down Expand Up @@ -192,7 +192,7 @@
}
}
},
"/v1/r/users/:user": {
"/v1/r/users/{user}": {
"get": {
"consumes": [
"application/json",
Expand All @@ -207,10 +207,17 @@
],
"summary": "Get User",
"parameters": [
{
"type": "string",
"description": "1",
"name": "user",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Bearer Token",
"name": "token",
"name": "Authorization",
"in": "header",
"required": true
}
Expand Down
11 changes: 8 additions & 3 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ paths:
parameters:
- description: Bearer Token
in: header
name: token
name: Authorization
required: true
type: string
produces:
Expand Down Expand Up @@ -175,16 +175,21 @@ paths:
summary: List of users
tags:
- User
/v1/r/users/:user:
/v1/r/users/{user}:
get:
consumes:
- application/json
- multipart/form-data
- application/x-www-form-urlencoded
parameters:
- description: "1"
in: path
name: user
required: true
type: string
- description: Bearer Token
in: header
name: token
name: Authorization
required: true
type: string
produces:
Expand Down
25 changes: 25 additions & 0 deletions infra/db/postgres_init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env sh
set -e

echo "[LOG] CREATE DATABASE IF NOT EXISTS $PGDATABASE"
env PGPASSWORD="$PGPASSWORD" PGHOST="$PGHOST" PGPORT="$PGPORT" psql -v ON_ERROR_STOP=1 --username "$PGUSER" --dbname "postgres" <<-EOSQL
SELECT 'CREATE DATABASE $PGDATABASE' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$PGDATABASE')\gexec
EOSQL

echo "[LOG] CREATE USER $DB_USERNAME IF NOT EXISTS"
env PGPASSWORD="$PGPASSWORD" PGHOST="$PGHOST" PGPORT="$PGPORT" psql -v ON_ERROR_STOP=1 --username "$PGUSER" --dbname "postgres" <<-EOSQL
DO
\$do$
BEGIN
IF EXISTS (
SELECT FROM pg_catalog.pg_roles
WHERE rolname = '$DB_USERNAME') THEN

RAISE NOTICE 'Role "$DB_USERNAME" already exists. Skipping.';
ELSE
CREATE ROLE $DB_USERNAME LOGIN ENCRYPTED PASSWORD '$DB_PASSWORD';
END IF;
END
\$do$;
GRANT ALL ON DATABASE $PGDATABASE TO $DB_USERNAME;
EOSQL
2 changes: 1 addition & 1 deletion repositories/userRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (repository *UserRepository) Migrate() (err error) {
}

func (repository *UserRepository) GetUsersWithPaginationAndOrder(pagination scopes.GormPager, order scopes.GormOrderer) (users []models.User, totalCount int64, err error) {
err = repository.DB().Scopes(order.ToOrder(models.User{}.TableName(), "id", "id", "created_at", "updated_at")).Count(&totalCount).Scopes(pagination.ToPaginate()).Find(&users).Error
err = repository.DB().Table(models.User{}.TableName()).Scopes(order.ToOrder(models.User{}.TableName(), "id", "id", "created_at", "updated_at")).Count(&totalCount).Scopes(pagination.ToPaginate()).Find(&users).Error
return
}

Expand Down
Loading