Пример #1
0
// returnSession returns an existing gameSession response to the response.
func returnGameSession(c web.C, w http.ResponseWriter, r *http.Request) {

	// Find the gameSession by the id parameter in the url
	gameSession, err := GetGameSessionBy("_id", bson.ObjectIdHex(c.URLParams["id"]))

	// GameSession could not be found
	if err != nil {
		io.WriteString(w, c.URLParams["id"]+" "+err.Error())
		w.WriteHeader(404)
		return
	}

	// Then we want to actually find the game
	game, err := GetGameBy("_id", bson.ObjectIdHex(gameSession.GameId))

	// Game could not be found
	if err != nil {
		io.WriteString(w, "game "+gameSession.GameId+" not found")
		w.WriteHeader(404)
		return
	}

	gameSessionResource := hal.NewResource(gameSession, "/sessions/"+gameSession.ID.Hex())
	gameResource := hal.NewResource(game, "/games/"+gameSession.GameId)

	gameSessionResource.Embed("game", gameResource)
	gameSessionResource.AddNewLink("game", "/games/"+gameSession.GameId)

	j, _ := json.Marshal(gameSessionResource)

	io.WriteString(w, string(j))
}
Пример #2
0
func main() {
	c := Category{
		Code: 1,
		Name: "Some Category",
	}

	p := Product{
		Code:     1,
		Name:     "Some Product",
		Price:    10,
		Category: c,
	}

	// Creating HAL Resources
	pr := hal.NewResource(p, "/products/1")
	cr1 := hal.NewResource(p.Category, "/categories/1")
	cr2 := hal.NewResource(p.Category, "/categories/2")
	cr3 := hal.NewResource(p.Category, "/categories/3")

	// Embeding categories into product
	pr.Embed("categories", cr1)
	pr.Embedded.Del("categories")
	pr.Embedded.Set("categories", cr2)
	pr.Embedded.Add("categories", cr3)

	// JSON Encoding
	j, err := json.MarshalIndent(pr, "", "  ")
	if err != nil {
		fmt.Printf("%s", err)
	}

	fmt.Printf("%s", j)
}
Пример #3
0
func newUser(w http.ResponseWriter, r *http.Request) {
	var user User

	// Read the user information out of the post body.
	body, _ := ioutil.ReadAll(r.Body)

	err := json.Unmarshal(body, &user)
	// Missing POST data
	if err != nil {
		w.WriteHeader(400)
		io.WriteString(w, errorResponse([]string{"Request Data does not match expected format"}))
		return
	}

	// Search for use by email to see if they already exist
	userCollection := DB.C("users")

	err = userCollection.Find(bson.M{"email": user.Email}).One(&user)

	// User was found
	if err == nil {
		w.WriteHeader(409)
		io.WriteString(w, errorResponse([]string{"User Exists"}))
		return
	}

	// Something else went wrong
	if err != mgo.ErrNotFound {
		w.WriteHeader(500)
		io.WriteString(w, errorResponse([]string{"Something really bad went wrong"}))
	}

	// Update the ser createdAt and insert the user
	user.CreatedAt = time.Now()
	err = userCollection.Insert(user)
	if err != nil {
		w.WriteHeader(500)
		io.WriteString(w, errorResponse([]string{err.Error()}))
		return
	}

	// Find the user by email to ensure it saved properly
	savedUser, err := GetUserBy("email", user.Email)

	// Something went wrong we couldn't find the saved user
	if err != nil {
		w.WriteHeader(400)
		io.WriteString(w, errorResponse([]string{"User did not save properly"}))
		return
	}

	userResponse := hal.NewResource(savedUser, "/users/"+savedUser.ID.Hex())

	j, _ := json.Marshal(userResponse)

	io.WriteString(w, string(j))

}
Пример #4
0
// root route (GET "/").
func root(w http.ResponseWriter, r *http.Request) {
	entrypoint := hal.NewResource(struct{}{}, "/")
	for name, path := range routes {
		entrypoint.AddNewLink(name, path)
	}

	j, _ := json.Marshal(entrypoint)

	io.WriteString(w, string(j))
}
Пример #5
0
func main() {
	// Creating HAL Resources
	r := hal.NewResource(Response{Count: 10, Total: 20}, "/tasks")
	r.AddNewLink("next", "/tasks=page=2")

	t1 := hal.NewResource(Task{Id: 1, Name: "Some Task"}, "/tasks/1")
	t2 := hal.NewResource(Task{Id: 2, Name: "Some Task"}, "/tasks/2")
	t3 := hal.NewResource(Task{Id: 3, Name: "Some Task"}, "/tasks/3")

	// Embeding tasks
	r.Embed("tasks", t1)
	r.Embed("tasks", t2)
	r.Embed("tasks", t3)

	// JSON Encoding
	j, err := json.MarshalIndent(r, "", "  ")
	if err != nil {
		fmt.Printf("%s", err)
	}

	fmt.Printf("%s", j)
}
Пример #6
0
// Responds to a POST request to create a new game
func newGame(w http.ResponseWriter, r *http.Request) {
	var game Game

	// Ensure the post body is available and is in correct JSON format
	body, _ := ioutil.ReadAll(r.Body)
	err := json.Unmarshal(body, &game)
	// Missing POST data
	if err != nil {
		w.WriteHeader(400)
		io.WriteString(w, errorResponse([]string{"json data is invalid"}))
		return
	}

	// Search the games collection to see if a game with this name already exists
	gameCollection := DB.C("games")

	_, err = GetGameBy("name", game.Name)

	// Game was found so we need to freak out.
	if err == nil {
		w.WriteHeader(409)
		io.WriteString(w, errorResponse([]string{game.Name + " already exists as a game"}))
		return
	}

	// Save the game to the database
	err = gameCollection.Insert(game)
	if err != nil {
		w.WriteHeader(400)
		io.WriteString(w, errorResponse([]string{err.Error()}))
		return
	}

	// If the game saved properly we want to fetch it back out
	savedGame, err := GetGameBy("name", game.Name)
	// Something went wrong and the game apparently wasn't saved properly
	if err != nil {
		w.WriteHeader(400)
		io.WriteString(w, errorResponse([]string{"Game did not save properly"}))
		return
	}

	gameResponse := hal.NewResource(savedGame, "/games/"+savedGame.ID.Hex())
	gameResponse.AddNewLink("sessions", "/sessions?gameId="+savedGame.ID.Hex())

	j, _ := json.Marshal(gameResponse)

	io.WriteString(w, string(j))
}
Пример #7
0
// returnUser returns an existing user response to the response.
func returnUser(c web.C, w http.ResponseWriter, r *http.Request) {

	user, err := GetUserBy("_id", bson.ObjectIdHex(c.URLParams["id"]))

	// Something went wrong
	if err != nil {
		io.WriteString(w, c.URLParams["id"]+" "+err.Error())
		w.WriteHeader(404)
		return
	}

	userResponse := hal.NewResource(user, "/users/"+user.ID.Hex())

	j, _ := json.Marshal(userResponse)

	io.WriteString(w, string(j))
}
Пример #8
0
// returnGame returns an existing game response to the response.
func returnGame(c web.C, w http.ResponseWriter, r *http.Request) {

	// Find the game by the id parameter in the url
	game, err := GetGameBy("_id", bson.ObjectIdHex(c.URLParams["id"]))

	// Game could not be found
	if err != nil {
		io.WriteString(w, c.URLParams["id"]+" "+err.Error())
		w.WriteHeader(404)
		return
	}

	gameResponse := hal.NewResource(game, "/games/"+game.ID.Hex())
	gameResponse.AddNewLink("sessions", "/sessions?gameId="+game.ID.Hex())

	j, _ := json.Marshal(gameResponse)

	io.WriteString(w, string(j))
}
Пример #9
0
func main() {
	p := Product{
		Code:  1,
		Name:  "Some Product",
		Price: 10,
	}

	// Creating HAL Resources
	pr := hal.NewResource(p, "/products/1")

	// Adding an extra link
	pr.AddNewLink("help", "/docs")

	// JSON Encoding
	j, err := json.MarshalIndent(pr, "", "  ")
	if err != nil {
		fmt.Printf("%s", err)
	}

	fmt.Printf("%s", j)
}
Пример #10
0
// returnGame returns all existing games
// Filters:
//    page
//    limit
func returnGames(c web.C, w http.ResponseWriter, r *http.Request) {

	// Get the page limit parameter and the current page parameter
	currentPage, _ := strconv.Atoi(r.URL.Query().Get("page"))
	if currentPage == 0 {
		currentPage = 1
	}
	pageLimit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
	if pageLimit == 0 {
		pageLimit = 10
	} else if pageLimit > 100 {
		pageLimit = 100
	}

	var games []Game

	// Get the count of pages and total games
	totalGames, err := DB.C("games").Count()
	totalPages := int(math.Ceil(float64(totalGames) / float64(pageLimit)))

	if err != nil {
		w.WriteHeader(401)
		return
	}

	// Start the query to find all the games
	query := DB.C("games").Find(bson.M{})

	// Modifications to the query to allow pagination
	if currentPage > 1 {
		query.Skip((currentPage - 1) * pageLimit)
	}

	query.Limit(pageLimit).All(&games)

	// We found no games
	if err != nil {
		io.WriteString(w, c.URLParams["id"]+" "+err.Error())
		w.WriteHeader(404)
		return
	}

	gameResponse := hal.NewResource(Collection{
		Count: len(games),
		Total: totalGames,
	}, "/games?page="+strconv.Itoa(currentPage))

	// Embed the pagination links
	if currentPage > 1 {
		gameResponse.AddNewLink("previous", "/games?page="+strconv.Itoa(currentPage-1))
	}
	if currentPage < totalPages {
		gameResponse.AddNewLink("next", "/games?page="+strconv.Itoa(currentPage+1))
		gameResponse.AddNewLink("last", "/games?page="+strconv.Itoa(totalPages))
	}

	// Add session linke to the games
	for _, game := range games {
		g := hal.NewResource(game, "/games/"+game.ID.Hex())

		g.AddNewLink("sessions", "/sessions?gameId="+game.ID.Hex())
		gameResponse.Embed("games", g)
	}

	j, _ := json.Marshal(gameResponse)

	io.WriteString(w, string(j))
}
Пример #11
0
// returnSession returns all existing sessions
// Filters:
//    gameId
//    page
//    limit
func returnGameSessions(c web.C, w http.ResponseWriter, r *http.Request) {
	var sessions []GameSession
	var totalSessions int
	var query *mgo.Query
	var err error
	var game *Game

	// Fetch the gameId filter if it is set
	gameId := r.URL.Query().Get("gameId")

	currentPage, _ := strconv.Atoi(r.URL.Query().Get("page"))
	if currentPage == 0 {
		currentPage = 1
	}

	pageLimit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
	if pageLimit == 0 {
		pageLimit = 10
	} else if pageLimit > 100 {
		pageLimit = 100
	}

	// Alter the query depending on if we have that gameId filter
	if len(gameId) > 0 {
		totalSessions, err = DB.C("gameSessions").Find(bson.M{"gameId": gameId}).Count()
		query = DB.C("gameSessions").Find(bson.M{"gameId": gameId})

		// Then we want to actually find the game
		game, err = GetGameBy("_id", bson.ObjectIdHex(gameId))

		// Game could not be found
		if err != nil {
			io.WriteString(w, "game "+gameId+" not found")
			w.WriteHeader(404)
			return
		}
	} else {
		totalSessions, err = DB.C("gameSessions").Count()
		query = DB.C("gameSessions").Find(bson.M{})
	}

	totalPages := int(math.Ceil(float64(totalSessions) / float64(pageLimit)))

	if currentPage > 1 {
		query.Skip((currentPage - 1) * pageLimit)
	}

	// Find all sessions up to the limit
	err = query.Limit(pageLimit).All(&sessions)

	// Something went wrong
	if err != nil {
		io.WriteString(w, c.URLParams["id"]+" "+err.Error())
		w.WriteHeader(404)
		return
	}

	sessionResponse := hal.NewResource(Collection{
		Count: len(sessions),
		Total: totalSessions,
	}, "/sessions?page="+strconv.Itoa(currentPage))

	// Link to the game information on the session
	for _, session := range sessions {
		s := hal.NewResource(session, "/sessions/"+session.ID.Hex())
		s.AddNewLink("game", "/games/"+session.GameId)

		// If the query has a gameId filter we want to embed that game into
		// each session.
		if len(gameId) > 0 {
			g := hal.NewResource(game, "/games/"+game.ID.Hex())

			s.Embed("game", g)
		}

		sessionResponse.Embed("sessions", s)
	}

	// Add the num pages links
	if currentPage > 1 {
		sessionResponse.AddNewLink("previous", "/sessions?page="+strconv.Itoa(currentPage-1))
	}
	if currentPage < totalPages {
		sessionResponse.AddNewLink("next", "/sessions?page="+strconv.Itoa(currentPage+1))
		sessionResponse.AddNewLink("last", "/sessions?page="+strconv.Itoa(totalPages))
	}

	j, _ := json.Marshal(sessionResponse)

	io.WriteString(w, string(j))
}
Пример #12
0
func newRound(c web.C, w http.ResponseWriter, r *http.Request) {
	var round Round

	// read the post body and get the data for the round into a round struct
	body, _ := ioutil.ReadAll(r.Body)
	err := json.Unmarshal(body, &round)

	// Missing POST data
	if err != nil {
		w.WriteHeader(400)
		io.WriteString(w, errorResponse([]string{"Request Data does not match expected format"}))
		return
	}

	// Find the game session this round belongs to
	gameSession, err := GetGameSessionBy("_id", bson.ObjectIdHex(round.GameSessionId))

	if err != nil {
		w.WriteHeader(400)
		io.WriteString(w, err.Error())
		io.WriteString(w, errorResponse([]string{"GameSession for round not found"}))
		return
	}

	// Detmine the number of rounds already in the game.
	roundCount := len(gameSession.Rounds)
	round.CreatedAt = time.Now()

	// Lets add this round to the collection of rounds shall we?
	gameSession.Rounds = append(gameSession.Rounds, round)
	gameSessionCollection := DB.C("gameSessions")

	// Update the game session record
	err = gameSessionCollection.Update(bson.M{"_id": bson.ObjectIdHex(round.GameSessionId)}, gameSession)

	if err != nil {
		w.WriteHeader(400)
		io.WriteString(w, errorResponse([]string{err.Error()}))
		return
	}

	// Fetch back the game session to validate it saved properly
	savedGS, err := GetGameSessionBy("_id", bson.ObjectIdHex(round.GameSessionId))

	// Something went wrong
	if err != nil {
		w.WriteHeader(400)
		io.WriteString(w, errorResponse([]string{"Round did not save properly"}))
		return
	}

	//We didn't add the round to the session
	if len(savedGS.Rounds)-1 != roundCount {
		w.WriteHeader(400)
		io.WriteString(w, errorResponse([]string{"Round did not save properly"}))
		return
	}

	gsResponse := hal.NewResource(savedGS, "/sessions/"+savedGS.ID.Hex())

	// Add player information to the game session
	for _, playerId := range savedGS.CountryPlayers {

		user, _ := GetUserBy("_id", bson.ObjectIdHex(playerId))

		gsResponse.Embed("players", hal.NewResource(user, "/users/"+user.ID.Hex()))
	}

	j, _ := json.Marshal(gsResponse)

	io.WriteString(w, string(j))
}
Пример #13
0
// newGameSession responds to a post request and create a new game session
// for a particular game.
func newGameSession(w http.ResponseWriter, r *http.Request) {
	var gameSession GameSession

	// Read the post body
	body, _ := ioutil.ReadAll(r.Body)

	// Unmarshal the json into the gameSession struct
	err := json.Unmarshal(body, &gameSession)

	// Missing required POST data to create a session
	if err != nil {
		w.WriteHeader(400)
		io.WriteString(w, errorResponse([]string{"Request Data does not match expected format"}))
		return
	}

	// Find the game associated with the session
	game, err := GetGameBy("_id", bson.ObjectIdHex(gameSession.GameId))

	// If the game does not exist, bork
	if err != nil {
		w.WriteHeader(400)
		io.WriteString(w, err.Error())
		io.WriteString(w, errorResponse([]string{"Game for game session not found"}))
		return
	}

	now := time.Now()
	gameSession.CreatedAt = now

	gameSessionCollection := DB.C("gameSessions")

	// Add the session to the db
	err = gameSessionCollection.Insert(gameSession)
	if err != nil {
		w.WriteHeader(400)
		io.WriteString(w, errorResponse([]string{err.Error()}))
		return
	}

	var savedGS GameSession

	// Try to fetch the saved session back
	err = gameSessionCollection.Find(bson.M{
		"userId":    gameSession.UserId,
		"createdAt": gameSession.CreatedAt,
	}).One(&savedGS)

	// Something went wrong the session didn't save right
	if err != nil {
		w.WriteHeader(400)
		io.WriteString(w, errorResponse([]string{"GameSession did not save properly"}))
		return
	}

	gameSessionResponse := hal.NewResource(savedGS, "/sessions/"+savedGS.ID.Hex())

	// Embed the countries and user information to the response
	for countryName, playerId := range savedGS.CountryPlayers {
		user, _ := GetUserBy("_id", bson.ObjectIdHex(playerId))
		for _, country := range game.Countries {
			if countryName == country.Name {
				gameSessionResponse.Embed("countries", hal.NewResource(country, ""))
			}
		}

		gameSessionResponse.Embed("players", hal.NewResource(user, "/users/"+user.ID.Hex()))
	}

	j, _ := json.Marshal(gameSessionResponse)

	io.WriteString(w, string(j))
}
Пример #14
0
// returnUser returns all existing users
// Filters:
//    page
//    limit
func returnUsers(c web.C, w http.ResponseWriter, r *http.Request) {
	//Setup the page and limit values
	currentPage, _ := strconv.Atoi(r.URL.Query().Get("page"))
	if currentPage == 0 {
		currentPage = 1
	}

	pageLimit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
	if pageLimit == 0 {
		pageLimit = 10
	} else if pageLimit > 100 {
		pageLimit = 100
	}

	var users []User

	// Get the total number os users and total number of pages
	totalUsers, err := DB.C("users").Count()
	totalPages := int(math.Ceil(float64(totalUsers) / float64(pageLimit)))

	// Thats not great ¯\_(ツ)_/¯
	if err != nil {
		io.WriteString(w, c.URLParams["id"]+" "+err.Error())
		w.WriteHeader(401)
		return
	}

	// Begin the find all users query
	query := DB.C("users").Find(bson.M{})

	// Filter the query by page
	if currentPage > 1 {
		query.Skip((currentPage - 1) * pageLimit)
	}

	// Limit the query
	query.Limit(pageLimit).All(&users)

	// Something went wrong
	if err != nil {
		w.WriteHeader(404)
		return
	}

	userResponse := hal.NewResource(Collection{
		Count: len(users),
		Total: totalUsers,
	}, "/users?page="+strconv.Itoa(currentPage))

	// Add pagination links to the response
	if currentPage > 1 {
		userResponse.AddNewLink("previous", "/users?page="+strconv.Itoa(currentPage-1))
	}
	if currentPage < totalPages {
		userResponse.AddNewLink("next", "/users?page="+strconv.Itoa(currentPage+1))
		userResponse.AddNewLink("last", "/users?page="+strconv.Itoa(totalPages))
	}

	// Embed the users to the collection
	for _, user := range users {
		userResponse.Embed("users", hal.NewResource(user, "/users/"+user.ID.Hex()))
	}

	j, _ := json.Marshal(userResponse)

	io.WriteString(w, string(j))
}