A GOLANG BACK END CODE FOR THE GROOVY API.
- Groovy is a full fledged API written in Golang. It's aimed as a project to show the creation of a robust back-end equipped with a myriad of features including authentication, authorization, permisions, CORS and email capabilities.
- The database at the heart of the application is POSTGRESQL and involves CRUD features for the entry, updating, deleting and reading of stored movie information which includes pagination, advanced searches and filtering.
- Introducing the sister project for this, the Groovy-Fronted, fully powered by Svelte.
These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.
Before you can run or contribute to this project, you'll need to have the following software installed:
- Go: The project is written in Go, so you'll need to have Go installed to run or modify the code.
- PostgreSQL: The project uses a PostgreSQL database, so you'll need to have PostgreSQL installed and know how to create a database.
- A Go IDE or text editor: While not strictly necessary, a Go IDE or a text editor with Go support can make it easier to work with the code. I use vscode.
- Git: You'll need Git to clone the repo.
-
Clone the repository: Start by cloning the repository to your local machine. Open a terminal, navigate to the directory where you want to clone the repository, and run the following command:
git clone https://github.com/blue-davinci/groovy.git
-
Navigate to the project directory: Use the
cd
command to navigate to the project directory:cd groovy
-
Install the Go dependencies: The Go tools will automatically download and install the dependencies listed in the
go.mod
file when you build or run the project. To download the dependencies without building or running the project, you can use thego mod download
command:go mod download
-
Set up the database: The project uses a PostgreSQL database. You'll need to create a new database and update the connection string in your configuration file or environment variables. The exact steps to do this depend on your PostgreSQL setup and can also be done via Migration files included in this repo via:
migrate -path=migrations -database=postgres://your_username:your_password@localhost/groovy?sslmode=disable up
-
Build the project: You can build the project using the
go build
command:go build
This will create an executable file in the current directory.
-
Run the project: You can run the project using the
go run
after navigating tocmd\api\
directory:go run .
-
Run the project: Instead of using
go run
, you can use themake
command with therun/api
target to run the project:make run/api
-
For additional supported commands run
make help
:
make help
The application accepts command-line flags for configuration, establishes a connection pool to a database, and publishes variables for monitoring the application. The published variables include the application version, the number of active goroutines, database connection pool statistics, and the current Unix timestamp.
This will start the application. You should be able to access it at http://localhost:4000
.
You can view the parameters by utilizing the -help
command. Here is a rundown of
the available commands for a quick lookup.
- smtp-sender: Sets the sender for SMTP (email) communications. Default: "Groovy no-reply@groovy.com".
- cors-trusted-origins: Sets the trusted origins for Cross-Origin Resource Sharing (CORS). Provide a space-separated list of origins.
- cors-trusted-origins [value]: Trusted CORS origins (space separated)
- db-dsn [string]: PostgreSQL DSN (default "{Path to your .env holding your DSN}")
- db-max-idle-conns [int]: PostgreSQL max idle connections (default 25)
- db-max-idle-time [string]: PostgreSQL max connection idle time (default "15m")
- db-max-open-conns [int]: PostgreSQL max open connections (default 25)
- env [string]: Environment (development|staging|production) (default "development")
- limiter-burst [int]: Rate limiter maximum burst (default 4)
- limiter-enabled [bool]: Enable rate limiter (default true)
- limiter-rps [float]: Rate limiter maximum requests per second (default 2)
- port [int]: API server port (default 4000)
- smtp-host [string]: SMTP host (default "sandbox.smtp.mailtrap.io"- I use mailtrap for tests)
- smtp-password [string]: SMTP password (default "xxxxx")
- smtp-port [int]: SMTP port (default 25)
- smtp-sender [string]: SMTP sender (default "Groovy no-reply@groovy.com")
- smtp-username [string]: SMTP username (default "skunkhunt42")
- baseurl [string]: frontend url (default "http://localhost:5173")
- activationurl [string]: frontend activation url (default "http://localhost:5173/verify?token=")
- passwordreseturl: frontend password reset url (default "http://localhost:5173/reset?token=")
Using make run
, will run the API with a default connection string: -db-dsn=${GROOVY_DB_DSN}
located
in cmd\api\.env
. If you're using powershell, you need to load the values otherwise you will get
a cannot load env file
error. Use the PS code below to load it or change the env variable:
$env:GROOVY_DB_DSN=(Get-Content -Path .\cmd\api\.env | Where-Object { $_ -match "GROOVY_DB_DSN" } | ForEach-Object { $($_.Split("=", 2)[1]) })
Alternatively, in unix systems you can make a .envrc file and load it directly in the makefile by importing like so:
include .envrc
A succesful run will output:
{"level":"INFO","time":"0000-00-00T16:50:52Z","message":"database connection pool established"}
{"level":"INFO","time":"0000-00-00T16:50:52Z","message":"starting server","properties":{"addr":":4000","env":"development"}}
{"level":"INFO","time":"0000-00-00T16:51:01Z","message":"shutting down server","properties":{"signal":"interrupt"}}
{"level":"INFO","time":"0000-00-00T16:51:01Z","message":"completing background tasks","properties":{"addr":":4000"}}
{"level":"INFO","time":"0000-00-00T16:51:01Z","message":"stopped server","properties":{"addr":":4000"}}
Below are all the end points for the API and a high level description of what they do.
-
GET /v1/healthcheck: Checks the health of the application. Returns a 200 OK status code if the application is running correctly.
-
GET /v1/movies: Lists all movies. Requires "movies:read" permission.
-
POST /v1/movies: Creates a new movie. Requires "movies:write" permission.
-
GET /v1/movies/:id: Shows details of a specific movie. Requires "movies:read" permission.
-
PATCH /v1/movies/:id: Updates a specific movie. Requires "movies:write" permission.
-
DELETE /v1/movies/:id: Deletes a specific movie. Requires "movies:write" permission.
-
POST /v1/users: Registers a new user.
-
PUT /v1/users/activated: Activates a user.
-
POST /v1/tokens/authentication: Creates an authentication token.
-
GET /debug/vars: Provides debug variables from the
expvar
package. -
PUT /v1/users/password: Accepts a user's new password
-
POST /v1/tokens/password-reset: Sends a token to the user for password reset requests
-
POST /v1/tokens/activation: Manual token sending for unregistered users incase of emeail failures/ token expiry.
The rate limiter test
Essentially checks whether rate limiting works, You need to run/start the API with
the limiter-burst
set to whatever you want and then can configure the number
of requests to check how many responses return with 200 vs 429 (too manu requests)
Sample output:
=== RUN TestRateLimit
groovy\cmd\api\middleware_test.go:45: handler returned wrong status code: got 200 want 429
--- FAIL: TestRateLimit (0.00s)
FAIL
FAIL groovy/cmd/api 0.398s
Simply run using the app/main.go using any number of flags you desire like below:
make build/api
./bin/api.exe -smtp-username=pigbearman -smtp-password=algor
Direct Run:
go run main.go
This application can be deployed using Docker and Docker Compose. Here are the steps to do so:
-
Build the Docker image: Run
docker build -t groovy .
while in the root directory . -
Run the Docker Compose services: Run
docker-compose up
while in the root dir.
If you want to run the services in the background, you can use the -d
option: docker-compose up -d
.
Please remember you can use flags, mentioned here while running the api by setting them in
the Dockerfile
like so:
CMD ["./bin/api.exe", "-smtp-username", "smtp username", "-port", "your_port", "-smtp-password", "your_smtp_pass"]
Remember to replace groovy
with the name you want to give to your Docker image. If you're pushing to Docker Hub, the image name should be in the format username/repository:tag
, where username
is your Docker Hub username, repository
is the name you want to give to your Docker repository, and tag
is the tag you want to give to this version of the image. If you don't specify a tag, Docker will use latest
by default.
Please note that you need to have Docker and Docker Compose installed on your machine to deploy the application this way. You can download Docker here and find installation instructions for Docker Compose here.
- PostgreSQL - Database
- Go - Backend
- HTML - Email Template
- JavaScript - Frontend behavior
- @blue-davinci - The Groovy API
- Hat tip to anyone whose framework was used
- Inspiration: This project was inspired by the desire to create a robust and scalable API using Go. The goal was to leverage Go's efficiency and performance, along with PostgreSQL's reliability and feature set, to build an application that can handle high loads and complex operations. The frontend examples were built with HTML, Bootstrap and jQuery, as a start in providing a user-friendly interface to interact with the API.
- Go Documentation: Official Go documentation and tutorials.
- PostgreSQL Documentation: Official PostgreSQL documentation.
- Go database/sql tutorial: Tutorial on using Go's database/sql package.