inital skeleton

This commit is contained in:
stryan 2022-03-03 13:28:00 -05:00
commit a50e4162b3
8 changed files with 190 additions and 0 deletions

6
README.md Normal file
View File

@ -0,0 +1,6 @@
# freego_api
freego implementation as a simple REST API.
Currently stores no state and has no user authentication, so using it should just be
go build
./freego_api

85
api.go Normal file
View File

@ -0,0 +1,85 @@
package main
import (
"encoding/json"
"net/http"
"strconv"
"github.com/gorilla/mux"
)
//API represents the api
type API struct {
games map[int]*Session
nextInt int
}
//NewAPI creates new API instance
func NewAPI() *API {
return &API{
games: make(map[int]*Session),
nextInt: 1,
}
}
//NewGame takes a POST and creates a new game
func (a *API) NewGame(res http.ResponseWriter, req *http.Request) {
a.games[a.nextInt] = NewSession()
respondWithJSON(res, http.StatusOK, newGameResp{a.nextInt, "red"})
a.nextInt = a.nextInt + 1
}
//GetGame returns current state of game, filtered accordingly
func (a *API) GetGame(res http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
id, err := strconv.Atoi(vars["id"])
if err != nil {
respondWithError(res, http.StatusBadRequest, "Invalid game ID")
return
}
var gr gameReq
decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&gr); err != nil {
respondWithError(res, http.StatusBadRequest, "Invalid resquest payload")
return
}
defer req.Body.Close()
if gr.PlayerID != "red" && gr.PlayerID != "blue" {
respondWithError(res, http.StatusBadRequest, "Bad player ID")
return
}
s, isset := a.games[id]
if !isset {
respondWithError(res, http.StatusBadRequest, "No such game")
return
}
respondWithJSON(res, http.StatusOK, gameResp{s.simulator})
return
}
//GetGameStatus returns current game status and turn number
func (a *API) GetGameStatus(res http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
id, err := strconv.Atoi(vars["id"])
if err != nil {
respondWithError(res, http.StatusBadRequest, "Invalid game ID")
return
}
var gr gameReq
decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&gr); err != nil {
respondWithError(res, http.StatusBadRequest, "Invalid resquest payload")
return
}
defer req.Body.Close()
if gr.PlayerID != "red" && gr.PlayerID != "blue" {
respondWithError(res, http.StatusBadRequest, "Bad player ID")
return
}
s, isset := a.games[id]
if !isset {
respondWithError(res, http.StatusBadRequest, "No such game")
return
}
respondWithJSON(res, http.StatusOK, gameStatusResp{s.simulator.State, s.moveNum})
}

27
api_types.go Normal file
View File

@ -0,0 +1,27 @@
package main
import "git.saintnet.tech/freego"
//type newGameReq struct{}
type newGameResp struct {
GameID int `json:"game_id"`
PlayerID string `json:"player_id"`
}
type gameReq struct {
PlayerID string `json:"player_id"`
}
type gameResp struct {
GameBoard *freego.Game `json:"board"`
}
type gameStatusReq struct {
PlayerID string `json:"player_id"`
}
type gameStatusResp struct {
GameStatus freego.GameState `json:"game_status"`
Move int `json:"move"`
}

10
go.mod Normal file
View File

@ -0,0 +1,10 @@
module git.saintnet.tech/freego_api
replace git.saintnet.tech/freego => ../freego
go 1.17
require (
git.saintnet.tech/freego v0.0.0-00010101000000-000000000000 // indirect
github.com/gorilla/mux v1.8.0 // indirect
)

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=

21
main.go Normal file
View File

@ -0,0 +1,21 @@
package main
import (
"log"
"net/http"
"github.com/gorilla/mux"
)
func main() {
api := NewAPI()
router := mux.NewRouter().StrictSlash(true)
//plot out routes
router.HandleFunc("/game", api.NewGame).Methods("POST")
router.HandleFunc("/game/{id}", api.GetGame).Methods("GET")
router.HandleFunc("/game/{id}/status", api.GetGameStatus).Methods("GET")
router.HandleFunc("/game/{id}/move", nil).Methods("POST")
router.HandleFunc("/game/{id}/move/{movenum}", nil).Methods("GET")
log.Fatal(http.ListenAndServe(":1379", router))
}

21
session.go Normal file
View File

@ -0,0 +1,21 @@
package main
import "git.saintnet.tech/freego"
//Session represents an active game
type Session struct {
simulator *freego.Game
redReady bool
blueReady bool
moveNum int
}
//NewSession creates a new game session
func NewSession() *Session {
return &Session{
simulator: freego.NewGame(),
redReady: false,
blueReady: false,
moveNum: 0,
}
}

18
util.go Normal file
View File

@ -0,0 +1,18 @@
package main
import (
"encoding/json"
"net/http"
)
func respondWithError(res http.ResponseWriter, code int, message string) {
respondWithJSON(res, code, map[string]string{"error": message})
}
func respondWithJSON(res http.ResponseWriter, code int, payload interface{}) {
response, _ := json.Marshal(payload)
res.Header().Set("Content-Type", "application/json")
res.WriteHeader(code)
res.Write(response)
}