Skip to content

Commit 7c1cff5

Browse files
Lairon Acosta GuardiasLairon Acosta Guardias
Lairon Acosta Guardias
authored and
Lairon Acosta Guardias
committed
initial commit
1 parent 124c655 commit 7c1cff5

20 files changed

+818
-1
lines changed

.gitignore

+13
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Created by https://www.toptal.com/developers/gitignore/api/go
2+
# Edit at https://www.toptal.com/developers/gitignore?templates=go
3+
4+
### Go ###
15
# Binaries for programs and plugins
26
*.exe
37
*.exe~
@@ -13,3 +17,12 @@
1317

1418
# Dependency directories (remove the comment below to include it)
1519
# vendor/
20+
21+
### Go Patch ###
22+
/vendor/
23+
/Godeps/
24+
25+
### ide config ###
26+
.idea
27+
28+
# End of https://www.toptal.com/developers/gitignore/api/go

Dockerfile

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Start from golang base image
2+
FROM golang:alpine as builder
3+
4+
# Add Maintainer info
5+
LABEL maintainer="Lairon Acosta <lairon14@gmail.com>"
6+
7+
# Install git.
8+
# Git is required for fetching the dependencies.
9+
RUN apk update && apk add --no-cache git
10+
11+
# Set the current working directory inside the container
12+
WORKDIR /app
13+
14+
# Copy go mod and sum files
15+
COPY go.mod go.sum ./
16+
17+
# Download all dependencies. Dependencies will be cached if the go.mod and the go.sum files are not changed
18+
RUN go mod download
19+
20+
# Copy the source from the current directory to the working Directory inside the container
21+
COPY . .
22+
23+
# Build the Go app
24+
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
25+
26+
# Start a new stage from scratch
27+
FROM alpine:latest
28+
RUN apk --no-cache add ca-certificates
29+
30+
WORKDIR /root/
31+
32+
# Copy migrations folder
33+
COPY ./migrations ./migrations
34+
35+
# Copy the Pre-built binary file from the previous stage. Observe we also copied the .env file
36+
COPY --from=builder /app/main .
37+
38+
# Expose port 8080 to the outside world
39+
EXPOSE 8080
40+
41+
#Command to run the executable
42+
CMD ["./main"]

README.md

+75-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,75 @@
1-
# ms-echo-go
1+
# Microservice: Echo Framework Example
2+
This project shows the use of Echo Framework in Golang.
3+
4+
This repository runs a simple main daemon (main) that implements a REST API for users. The daemon uses a postgres database to persist data and after creation uses migrations to create the user schema.
5+
6+
## Table of Contents
7+
8+
- [Running](#running)
9+
- [Dependencies](#dependencies)
10+
- [Environment Variables](#environment-variables)
11+
- [Make Rule](#make-rule)
12+
- [Testing](#testing)
13+
- Coming soon
14+
15+
## Running
16+
17+
### Dependencies
18+
19+
The only dependencies to run the services in this repository are:
20+
21+
- `docker`
22+
- `docker-compose`
23+
24+
### Environment Variables
25+
26+
The program looks for the following environment variables:
27+
28+
- `DB_USER`: The postgres database username that gets used within the postgres connection
29+
string (Default: `root`).
30+
- `DB_PASS`: The postgres database password that gets used within the postgres connection
31+
string (Default: `root`).
32+
- `DB_NAME`: The postgres database name that gets used within the postgres connection string
33+
(Default: `user`).
34+
- `DB_HOST`: The postgres database host name that gets used within the postgres connection
35+
string (Default `db`).
36+
- `DB_PORT`: The postgres database port that gets used within the postgres connection string
37+
(Default: `5432`).
38+
39+
If the environment variable has a supplied default and none are set within the context of the host
40+
machine, then the default will be used.
41+
42+
To set any given environment variable, simply execute the following
43+
pattern, replacing `[ENV_NAME]` with the name of the environment variable and `[ENV_VALUE]` with the
44+
desired value of the environment variable: `export [ENV_NAME]=[ENV_VALUE]`. To unset any set environment
45+
variable, simply execute the following pattern, replacing `[ENV_NAME]` with the name of the environment
46+
variable: `unset [ENV_NAME]`.
47+
48+
### Make Rule
49+
50+
To run the services simply execute the following command:
51+
52+
```shell
53+
make run
54+
```
55+
56+
This will stop any containers defined by the compose file if already running
57+
and then rebuild the containers using the compose file. The main daemon (`main`)
58+
will be available at `localhost:8080` and the postgres instance will be available
59+
at `localhost:5432`.
60+
61+
To stop the services simply execute the following command:
62+
63+
```shell
64+
make stop
65+
```
66+
67+
To down the services simply execute the following command:
68+
69+
```shell
70+
make down
71+
```
72+
73+
## Testing
74+
75+
Coming soon
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package dto
2+
3+
type CreateUserRequest struct {
4+
Name string `json:"name" binding:"required"`
5+
Email string `json:"email" binding:"required,email"`
6+
}

controllers/dto/response.go

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package dto
2+
3+
type Response struct {
4+
Message string `json:"message"`
5+
}
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package dto
2+
3+
type UpdateUserRequest struct {
4+
Name string `json:"name" binding:"required"`
5+
}

controllers/dto/user_dto.go

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package dto
2+
3+
type User struct {
4+
Name string `json:"name" binding:"required"`
5+
Email string `json:"email" binding:"required,email"`
6+
}

controllers/health_controller.go

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package controllers
2+
3+
import (
4+
"github.com/labstack/echo"
5+
"github.com/laironacosta/ms-echo-go/controllers/dto"
6+
"net/http"
7+
)
8+
9+
func Health(c echo.Context) error {
10+
return c.JSON(http.StatusOK, dto.Response{
11+
Message: "ok",
12+
})
13+
}

controllers/users_controller.go

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package controllers
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"github.com/labstack/echo"
7+
"github.com/laironacosta/ms-echo-go/controllers/dto"
8+
"github.com/laironacosta/ms-echo-go/services"
9+
"net/http"
10+
)
11+
12+
type UserControllerInterface interface {
13+
Create(c echo.Context) error
14+
GetByEmail(c echo.Context) error
15+
UpdateByEmail(c echo.Context) error
16+
DeleteByEmail(c echo.Context) error
17+
}
18+
19+
type UserController struct {
20+
userService services.UserServiceInterface
21+
}
22+
23+
func NewUserController(userService services.UserServiceInterface) UserControllerInterface {
24+
return &UserController{
25+
userService,
26+
}
27+
}
28+
29+
func (ctr *UserController) Create(c echo.Context) error {
30+
u := dto.CreateUserRequest{}
31+
if err := c.Bind(&u); err != nil {
32+
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
33+
}
34+
35+
if err := ctr.userService.Create(context.Background(), u); err != nil {
36+
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
37+
}
38+
39+
fmt.Printf("Request received: %+v \n", u)
40+
return c.JSON(http.StatusOK, dto.Response{
41+
Message: "created",
42+
})
43+
}
44+
45+
func (ctr *UserController) GetByEmail(c echo.Context) error {
46+
e := c.Param("email")
47+
fmt.Printf("Path param received: %+v \n", e)
48+
49+
u, err := ctr.userService.GetByEmail(context.Background(), e)
50+
if err != nil {
51+
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
52+
}
53+
return c.JSON(http.StatusOK, u)
54+
}
55+
56+
func (ctr *UserController) UpdateByEmail(c echo.Context) error {
57+
u := dto.UpdateUserRequest{}
58+
if err := c.Bind(&u); err != nil {
59+
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
60+
}
61+
62+
e := c.Param("email")
63+
64+
fmt.Printf("Request received: %+v \n", u)
65+
fmt.Printf("Path param received: %+v \n", e)
66+
67+
if err := ctr.userService.UpdateByEmail(context.Background(), u, e); err != nil {
68+
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
69+
}
70+
return c.JSON(http.StatusOK, dto.Response{
71+
Message: "updated",
72+
})
73+
}
74+
75+
func (ctr *UserController) DeleteByEmail(c echo.Context) error {
76+
e := c.Param("email")
77+
78+
fmt.Printf("Path param received: %+v \n", e)
79+
80+
if err := ctr.userService.DeleteByEmail(context.Background(), e); err != nil {
81+
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
82+
}
83+
return c.JSON(http.StatusOK, dto.Response{
84+
Message: "deleted",
85+
})
86+
}

docker-compose.yml

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
version: '3'
2+
3+
networks:
4+
ms-go-network:
5+
driver: bridge
6+
7+
services:
8+
app:
9+
build:
10+
context: .
11+
dockerfile: ./Dockerfile
12+
ports:
13+
- "8080:8080"
14+
depends_on:
15+
- db
16+
restart: on-failure
17+
networks:
18+
- ms-go-network
19+
db:
20+
image: postgres:13.2
21+
ports:
22+
- "5432:5432"
23+
expose:
24+
- "5432"
25+
environment:
26+
POSTGRES_USER: root
27+
POSTGRES_PASSWORD: root
28+
POSTGRES_DB: user
29+
restart: on-failure
30+
networks:
31+
- ms-go-network

go.mod

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module github.com/laironacosta/ms-echo-go
2+
3+
go 1.16
4+
5+
require (
6+
github.com/dropbox/godropbox v0.0.0-20200228041828-52ad444d3502 // indirect
7+
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
8+
github.com/facebookgo/stackerr v0.0.0-20150612192056-c2fcf88613f4 // indirect
9+
github.com/go-pg/migrations/v8 v8.1.0
10+
github.com/go-pg/pg/v10 v10.9.0
11+
github.com/juju/errors v0.0.0-20200330140219-3fe23663418f // indirect
12+
github.com/kelseyhightower/envconfig v1.4.0
13+
github.com/labstack/echo v3.3.10+incompatible
14+
github.com/labstack/gommon v0.3.0 // indirect
15+
github.com/laironacosta/kit-go v1.0.0
16+
github.com/signalfx/golib v2.5.1+incompatible
17+
github.com/smartystreets/goconvey v1.6.4 // indirect
18+
)

0 commit comments

Comments
 (0)