Im building a server in Golang that returns data from a local json file. I have built the relevant structs and can get the server to return ALL the information from the json file, but what if i only want it to return certain entries?
Is there a way to query the data. I want the user to be able to enter a parameter into the url, the ID, and the relevant json be returned for the corresponding entry with that ID.
See the code for more info:
func main() {
//Initialises basic router and endpoints
r := mux.NewRouter()
r.HandleFunc("/", getAll).Methods("GET")
r.HandleFunc("/games/{id:[0-9]+}", getGame).Methods("GET")
r.HandleFunc("/games/report/{id}", getReport).Methods("GET")
fmt.Println("Listening on port 8080")
http.ListenAndServe(":8080", r)
}
Current code to retrieve all data from Json file.
func getAll(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
// Open jsonFile and handle the error
jsonFile, err := os.Open("./data/games.json")
if err != nil {
fmt.Println(err)
}
fmt.Println("Successfully Opened games.json")
// defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close()
// read the opened file as a byte array.
byteValue, _ := ioutil.ReadAll(jsonFile)
// initialize our Games array
var games models.Games
// unmarshal our byteArray which contains our
// jsonFile's content into 'games' which we defined above
json.Unmarshal(byteValue, &games)
json.NewEncoder(w).Encode(games)
}
Relevant Structs:
type Games struct {
Games []Game `json:"games"`
}
type Comment struct {
User string `json:"user"`
Message string `json:"message"`
DateCreated string `json:"dateCreated"`
Like int `json:"like"`
}
type Game struct {
ID int `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
By string `json:"by"`
Platform string `json:"platform"`
AgeRating string `json:"age_rating"`
Likes int `json:"likes"`
Comment Comment `json:"comments"`
}
As you should be able to see from the router, I want the user to pass in the {id} parameter which then gets inserted into a query. Is what im asking possible?
As Parham Alvani suggested, load your games into a map, but with pointer values, like this:
gameMap := make(map[string]*Game)
for _, game := range games{
gameMap[game.ID] = &game
}
in your GET /game-route you can pass the id of the game to the map, and return its result in whatever fashion you like, if it doesn't exist the pointer value will be nil and you can return a 404:
game := gameMap[id]
if game == nil{ // return 404}