This web service provides a REST api to allow users to pin areas they've visited and potentially share them with other users.
The following should get you up and running on a linux environment.
# Install rethinkdb according to: https://www.rethinkdb.com/docs/install/
# Run rethinkdb
rethinkdb
# Setup the repo (in a new shell)
go get github.com/nstogner/beenthere-ws.git
cd $GOPATH/src/github.com/nstogner/beenthere-ws
go test && go build
# Setup db schema
./beenthere-ws --init-db
# Run the web service
SERVER_PORT=4000 ./beenthere-ws
Configuration is done via environment variables. This allows for easy container deployment.
Variable | Default | Description |
---|---|---|
SERVER_PORT | 8080 | Port to listen for http traffic |
DB_PORT | 28015 | Port to talk to database |
DB_HOST | localhost | Host to connect to database |
DB_NAME | been_there | Name of the "database" inside of the database |
VISITS_TABLE | visits | Table in which to store user visits |
CITIES_TABLE | cities | Table in which to store city info |
Method | URL | Function |
---|---|---|
GET | /states/:state/cities | Getting a list of cities from in a given state |
POST | /users/:user/visits | Adding a visit record for a given user |
DELETE | /users/:user/visits/:visitId | Removing a visit record for a given user |
GET | /users/:user/visits | Getting a list of visit for a given user (paginated) |
GET | /users/:user/visits/cities | Getting a list of unique city names visited by a given user |
GET | /users/:user/visits/states | Getting a list of unique state names visited by a given user |
GET | /stream/visits | Stream new visits using Server Sent Events |
Pagination: Pagination is done via query parameters: "start" and "limit".
RethinkDB is used as the data-store. This NoSQL database was mainly chosen for it's streaming features. A social application such as this one could benefit from a feed of real-time user updates. In addition to streaming, RethinkDB aims to be very easy to administer, which reduces operational burden.
User authentication probably should exist in another service. This design would have a better seperation of concerns than lumping user-access in with user-visit functionality.
When a user adds a visit, the state is currently validated against an in-memory map of US states. This is done so that validating the given state does not require a database call and thereby slow down every new visit request.
Since there are a great number of cities, the in-memory map (used with states) is less feasible. Cities could be handled in several different manners:
- Accept all cities upon new visit request, validate city offline (what would you do about invalidated visits?)
- Maintain a source of truth of cities in the database & validate on each new visit request
- Create Dockerfile
- Create Kubernetes files
- Possibly remove hardcoded list of states, and read from db on startup (slower startup time, better seperation of data/logic)