inital skeleton
This commit is contained in:
commit
a50e4162b3
6
README.md
Normal file
6
README.md
Normal 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
85
api.go
Normal 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
27
api_types.go
Normal 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
10
go.mod
Normal 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
2
go.sum
Normal 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
21
main.go
Normal 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
21
session.go
Normal 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
18
util.go
Normal 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)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user