0

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?

4
  • You can use the third party routers like gorilla to parse URL parameters or you can do it manually by splitting the request.URL.Path. Commented Jul 4, 2019 at 21:44
  • I know how to parse the url parameter, But how do i then apply it to the json? Commented Jul 4, 2019 at 21:45
  • You can parse JSON into map and then use keys to retrieve the JSON values. Commented Jul 4, 2019 at 21:47
  • Or you can take a look at this. By using the unsafe parser you can query the keys as fastest as you can. Commented Jul 4, 2019 at 21:48

1 Answer 1

2

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}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.