A simple REST server written from scratch in Golang to practice the basics of developing an API service. The server simulates a locally running "BlueSky/Twitter-like" API where users, register, login, post, and view messages.
Guided project using backend developer training site boot.dev.
Concepts covered:
GET,POST,PUT,DELETEoperations- PostgresSQL acceess and storage
- Database migrations
- User authentication
- Endpoint authorization
- Query parameters
- Middleware functions
- 3rd-party webhooks
- HTTP unit testing
-
Install Go 1.23.1+
-
Install project libraries
go install -
Install SQLC:
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest -
Install Goose:
go install github.com/pressly/goose/v3/cmd/goose@latest -
Install the
Delvedebugger: https://github.com/go-delve/delve/tree/master/Documentation/installation -
(Optional) Install an API client (ex: Postman)
-
Install PostgresSQL (Mac):
brew install postgresql@15 -
Run in the background:
brew services start postgresql@15 -
Use a client to connect (ex:
psql):psql postgres -
Create the blank database:
CREATE DATABASE chirpy;
-
Create a file named
.envin the root directory and add it to .gitgnore. DO NOT COMMIT .env. -
In
.env, add the following variables:DB_URL="postgres://<username>:<password>@localhost:5432/chirpy?sslmode=disable" PLATFORM="dev" JWT_SECRET="TODO: Steps to generate" POLKA_API_KEY="<random, alphanumeric 32-char fake api key>"
-
From the root directory:
go run . -
Run
POST http://localhost:8080/api/resetto delete *all users and posts, clearing the database- Can also use during development testing
- Send requests to
http://localhost:8080/<endpoint> - Use
http://localhost:8080/admin/resetto clear the database
See the OpenApi 3.1 specifications (manually created).
-
Create new Goose migration file, place in
sql/schema. -
Run migration:
cd sql/schema goose postgres <postgress connection string> up # Rollback last migration (if needed) goose postgres <postgress connection string> down
Use SQLC to generate GO functions from SQL queries:
-
Add plain SQL queries here:
sql/schema -
Generate Go functions:
cd <base directory> sqlc generate
-
Access queries from the
apiConfigstruct:func (cfg *apiConfig) myHandler() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { result, err := cfg.db.MySQLFunction(...) } }
See the existing handler functions for more examples.
Handlers are set in main.go with implementation in seperate files.
-
Start the Delve debugger:
dlv debug . --headless --listen=:12345 --continue --accept-multiclient -
Connect to the debugger
- Working VSCode
launch.jsonconfig:
{ "version": "0.2.0", "configurations": [ { "name": "Connect to external session", "type": "go", "debugAdapter": "dlv-dap", "request": "attach", "mode": "remote", "port": 12345 // "host": "127.0.0.1", // can skip for localhost } ] } - Working VSCode
-
Set breakpoints in code
-
Send requests to server (ex: using Postman)
-
Step debug
- Unit tests:
go test ./...
- Implement code test coverage
- Experiment with fuzz testing with Go's testing libraries
- Local Front-end interface
- Deployment to cloud service; publicly accessible