From b4939a6fad235bd05cc3d6ee6fb023b444ccc0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Machado?= Date: Wed, 15 May 2024 22:47:56 +0100 Subject: [PATCH 1/2] added docker files and env variables --- .env | 3 ++ Dockerfile | 14 ++++++++++ README.md | 16 +++++++++-- docker-compose.yaml | 9 ++++++ main.go | 68 ++++++++++++++++----------------------------- 5 files changed, 64 insertions(+), 46 deletions(-) create mode 100644 .env create mode 100644 Dockerfile create mode 100644 docker-compose.yaml diff --git a/.env b/.env new file mode 100644 index 0000000..6efcf0e --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +BUCKET=sample_bucket +PORT=55555 +DB_PATH=sample_db.db \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0bb7419 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM golang:1.21 AS builder + +WORKDIR /app +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN go build -o main . + +FROM alpine:latest + +WORKDIR /app +COPY --from=builder /app/main . +EXPOSE 8080 +CMD ["./main"] \ No newline at end of file diff --git a/README.md b/README.md index f0a60c6..614631b 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,20 @@ The RESTful API is described in an OpenAPI 3.0 document found here: ([openapi.js Running ======= -```bash -usage: ./rest-api-microservice-demo db_path [port] [db_bucket_name] +**Native** +```sh +go run main.go +``` + +**Docker** +```sh +docker build -t rest-api-microservice-demo . +docker run -p ${PORT}:${PORT} rest-api-microservice-demo +``` + +**Docker Compose** +```sh +docker-compose up --build ``` Testing diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..cb1b665 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,9 @@ +services: + go-service: + build: . + ports: + - "${PORT}:${PORT}" + environment: + - BUCKET=${BUCKET} + - PORT=${PORT} + - DB_PATH=${DB_PATH} \ No newline at end of file diff --git a/main.go b/main.go index d85ac23..209deb9 100644 --- a/main.go +++ b/main.go @@ -9,60 +9,40 @@ import ( "github.com/brandonto/rest-api-microservice-demo/db" ) -const defaultDbBucketName = "DetailedMessageBucket" -const defaultPort = uint64(55555) - -func main() { - // Outputs usage if number of arguments are off - // - if len(os.Args) > 4 || len(os.Args) < 2 { - fmt.Println("usage: " + os.Args[0] + " db_path [port] [db_bucket_name]") - return - } - - // First argument is the filepath of the database - // - dbFile := os.Args[1] - - // Second (optional) argument is the the port number - // - port := defaultPort - if len(os.Args) > 2 { - // Some sanity check for the port argument before using - // - var err error - port, err = strconv.ParseUint(os.Args[2], 10, 64) - if err != nil { - fmt.Println("port argument must be an unsigned integer") - return - } +const ( + envDbBucketName = "BUCKET" + envPortName = "PORT" + dbPathName = "DB_PATH" +) - if port < uint64(49152) || port > uint64(65535) { - fmt.Println("port argument must be a value between 49152–65535") - return - } +func getConfig() core.Config { + envPort, cP := os.LookupEnv(envPortName) + bucket, cB := os.LookupEnv(envDbBucketName) + dbFile, cD := os.LookupEnv(dbPathName) + if !cP || !cB || !cD { + fmt.Errorf("enviroment variables: [%s, %s, %s] are required...", envDbBucketName, envPortName, dbPathName) } - - // Third (optional) argument is the the bucket name - // - dbBucketName := defaultDbBucketName - if len(os.Args) > 3 { - dbBucketName = os.Args[3] + port, err := strconv.ParseUint(envPort, 10, 64) + if err != nil { + fmt.Errorf("PORT environment variable must be an unsigned integer, value was: %s", envPort) } - // Configure and run the application - // - dbCfg := db.Config{ - FilePath: dbFile, - BucketName: dbBucketName, + if port < uint64(49152) || port > uint64(65535) { + fmt.Errorf("PORT environment variable must be a value between 49152–65535, value was: %s", envPort) } coreCfg := core.Config{ - DbCfg: dbCfg, + DbCfg: db.Config{ + FilePath: dbFile, + BucketName: bucket, + }, Port: port, EnableLogger: true, Standalone: true, } + return coreCfg +} - core.Run(coreCfg) +func main() { + core.Run(getConfig()) } From b905340347a0e204b793047668c4ddf5a45195b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Machado?= Date: Wed, 15 May 2024 23:22:22 +0100 Subject: [PATCH 2/2] added swagger documentation --- swagger.yaml | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 swagger.yaml diff --git a/swagger.yaml b/swagger.yaml new file mode 100644 index 0000000..148cbe2 --- /dev/null +++ b/swagger.yaml @@ -0,0 +1,106 @@ +openapi: 3.0.3 +info: + title: REST API Microservice Demo + description: A simple REST API microservice. + version: 1.0.0 +servers: + - url: http://localhost:8080 + description: Local server + +paths: + /messages: + get: + summary: Get all messages + operationId: getMessages + responses: + '200': + description: A list of messages + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Message' + post: + summary: Create a new message + operationId: createMessage + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Message' + responses: + '201': + description: Message created + content: + application/json: + schema: + $ref: '#/components/schemas/DetailedMessage' + + /messages/{messageId}: + get: + summary: Get a message by ID + operationId: getMessageById + parameters: + - name: messageId + in: path + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: A message with metadata + content: + application/json: + schema: + $ref: '#/components/schemas/DetailedMessage' + '404': + description: Message not found + delete: + summary: Delete a message by ID + operationId: deleteMessage + parameters: + - name: messageId + in: path + required: true + schema: + type: integer + format: int64 + responses: + '204': + description: Message deleted + '404': + description: Message not found + +components: + schemas: + Message: + type: object + properties: + id: + type: integer + format: int64 + payload: + type: string + required: + - id + - payload + + MessageMetadata: + type: object + properties: + palindrome: + type: boolean + + DetailedMessage: + type: object + properties: + message: + $ref: '#/components/schemas/Message' + metadata: + $ref: '#/components/schemas/MessageMetadata' + required: + - message + - metadata \ No newline at end of file