Skip to content

Repository files navigation

Roda Belém — API

Go REST API behind Roda Belém, the crowdsourced accessibility map for Belém, Pará. Places, reviews with accessibility tagging, users with points, favourites — with the geospatial and filtering work pushed into SQL where it belongs.

Design decisions worth the read

  • sqlc instead of an ORM. Queries live as real SQL in sql/queries/{places,reviews,users,favorites}.sql and are compiled into a typed Go package (internal/infra/mysql/db). No query builder guessing, no runtime reflection — and sqlc.yaml overrides decimal → float64 so the generated types match the domain.
  • Radius search in the database. Nearby lookup is ST_DISTANCE_SPHERE(POINT(lat, lng), POINT(?, ?)) <= ? (MySQL 8 spatial), so the API never pages a city's venues into memory to filter them.
  • Accessibility filtering pushed down too. FIND_IN_SET(?, accessibility_features) answers "show me every place with a ramp" in one indexed pass.
  • A cuckoo filter in front of Google Places. FindNearbyPlacesUseCase keeps a 10M-entry panmari/cuckoofilter of seen place IDs to drop duplicates before enrichment, which is what makes repeated map pans cheap.
  • Ports and adapters, honestly applied. domain/ declares PlacesGateway, ReviewsGateway, UsersGateway; usecase/ depends only on those interfaces; infra/repository/ implements them against MySQL. Swapping the store touches one directory.
  • JWT at the middleware layer. infra/web/middlewares/authentication_jwt.go guards the mutating routes; POST /users/login returns the token in the Authorization response header.

Layout

cmd/app/main.go              → wiring: repositories → use cases → handlers → chi router
internal/
  domain/                    → entities + gateway interfaces
  usecase/{places,review,user}/
  infra/
    web/                     → handlers, webserver.go, JWT middleware, CORS
    repository/              → MySQL implementations of the gateways
    mysql/db/                → sqlc-generated queries (do not edit by hand)
sql/
  migrations/                → schema (goose format)
  queries/                   → the SQL sqlc compiles

Data model

Table Columns of note
users id UUID, email unique, avatar MEDIUMBLOB, points INT, missions JSON
places google_place_id, lat/lng FLOAT, types/opening_periods/photos JSON, rating
reviews place_id → places, user_id → users, accessibility_features TEXT, reactions JSON (cascading delete)
favorites place_id + user_id many-to-many (cascading delete)

API

PlacesPOST /places/create · GET /places/find?id= · GET /places/nearby?lat=&lng=&radius=&isFromGoogle= · GET /places/accessibility?feature= · POST /places/update · DELETE /places/delete?id=

ReviewsGET /reviews/find?id= · GET /reviews/find-by-userid?userId= · GET /reviews/find-by-placeid?placeId= · (auth) POST /reviews/create · POST /reviews/update · DELETE /reviews/delete?id= · GET /reviews/add-feature?reviewId=&feature=

UsersPOST /users/create · POST /users/login · GET /users/list · GET /users/find?id= · GET /users/find-by-email?email= · (auth) POST /users/update · GET /users/update-points?userId=&points= · GET /users/add-favorite?userId=&placeId= · DELETE /users/delete-favorite?userId=&placeId= · GET /users/favorite?userId=

Stack

Go 1.20 · chi v5 · sqlc · MySQL 8 · JWT · googlemaps/maps for Place enrichment · viper · rs/cors · cuckoofilter · Docker + Compose

Run it

cp .env.example .env      # DB_USER DB_PASSWORD DB_HOST DB_PORT DB_NAME
                          # GOOGLE_MAPS_API_KEY JWT_SECRET_KEY
docker compose up -d      # API on :8080, MySQL on :3306
# or
go run cmd/app/main.go

Regenerate the query layer after editing sql/queries/:

sqlc generate

Status

Feature-complete: full CRUD for places, reviews and users, geospatial and accessibility filtering, favourites, points, JWT auth. Known gaps: pagination exists only on review queries, request validation is thin, and config failures panic rather than degrade. The old hosted instance is offline — run it with Compose.

About

Go REST API behind Roda Belém: sqlc-generated MySQL queries, ST_DISTANCE_SPHERE radius search, accessibility-feature filtering and JWT auth over clean architecture.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages