Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
package main

import (
"net/http"
"strconv"
"strings"

"github.com/gin-gonic/gin"
)

// User represents a user in our system
type User struct {
ID int `json:"id" binding:"omitempty,number"`
Name string `json:"name" binding:"required"`
Email string `json:"email" binding:"required,email"`
Age int `json:"age" binding:"required,number"`
}

// Response represents a standard API response
type Response struct {
Success bool `json:"success"`
Data interface{} `json:"data,omitempty"`
Message string `json:"message,omitempty"`
Error string `json:"error,omitempty"`
Code int `json:"code,omitempty"`
}

// In-memory storage
var users = []User{
{ID: 1, Name: "John Doe", Email: "[email protected]", Age: 30},
{ID: 2, Name: "Jane Smith", Email: "[email protected]", Age: 25},
{ID: 3, Name: "Bob Wilson", Email: "[email protected]", Age: 35},
}
var nextID = 4

func main() {
router := gin.Default()

// TODO: Setup routes
// GET /users - Get all users
router.GET("/users", getAllUsers)
// GET /users/:id - Get user by ID
router.GET("/users/:id", getUserByID)
// POST /users - Create new user
router.POST("/users", createUser)
// PUT /users/:id - Update user
router.PUT("/users/:id", updateUser)
// DELETE /users/:id - Delete user
router.DELETE("/users/:id", deleteUser)
// GET /users/search - Search users by name
router.GET("/users/search", searchUsers)

router.Run("localhost:8080")
}
Comment on lines +36 to +54
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix route registration order to prevent conflict.

The route /users/search (line 51) is registered after /users/:id (line 43). In Gin's router, parameterized routes like :id match any path segment, including "search". This means requests to /users/search will be incorrectly handled by getUserByID with id="search", and the search endpoint will never be reached.

Apply this diff to register the specific route before the parameterized one:

 	// GET /users - Get all users
 	router.GET("/users", getAllUsers)
+	// GET /users/search - Search users by name
+	router.GET("/users/search", searchUsers)
 	// GET /users/:id - Get user by ID
 	router.GET("/users/:id", getUserByID)
 	// POST /users - Create new user
 	router.POST("/users", createUser)
 	// PUT /users/:id - Update user
 	router.PUT("/users/:id", updateUser)
 	// DELETE /users/:id - Delete user
 	router.DELETE("/users/:id", deleteUser)
-	// GET /users/search - Search users by name
-	router.GET("/users/search", searchUsers)
🤖 Prompt for AI Agents
In packages/gin/challenge-1-basic-routing/submissions/AlexO-85/solution.go
around lines 36 to 54, the parameterized route router.GET("/users/:id",
getUserByID) is registered before the specific route router.GET("/users/search",
searchUsers), causing "/users/search" to be captured as an id; move the
router.GET("/users/search", searchUsers) registration so it appears before
router.GET("/users/:id", getUserByID) to ensure the specific search route is
matched first.


// TODO: Implement handler functions

// getAllUsers handles GET /users
func getAllUsers(c *gin.Context) {
response := Response{
Success: true,
Data: users,
}
c.IndentedJSON(http.StatusOK, response)
}

// getUserByID handles GET /users/:id
func getUserByID(c *gin.Context) {
idStr := c.Param("id")
// Handle invalid ID format
id, err := strconv.Atoi(idStr)
if err != nil {
response := Response{
Success: false,
Error: "User ID format is wrong",
Message: err.Error(),
Code: http.StatusBadRequest,
}
c.IndentedJSON(http.StatusBadRequest, response)
return
}

if user, _ := findUserByID(id); user != nil {
response := Response{
Success: true,
Data: user,
}
c.IndentedJSON(http.StatusOK, response)
return
}

response := Response{
Success: false,
Error: "User not found",
Code: http.StatusNotFound,
}

c.IndentedJSON(http.StatusNotFound, response)
}

// createUser handles POST /users
func createUser(c *gin.Context) {
var user User

if err := c.ShouldBindJSON(&user); err != nil {
response := Response{
Success: false,
Error: "Bas request",
Message: err.Error(),
Code: http.StatusBadRequest,
}
c.IndentedJSON(http.StatusBadRequest, response)
return
}

user.ID = nextID
users = append(users, user)
nextID++

response := Response{
Success: true,
Data: user,
}
c.IndentedJSON(http.StatusCreated, response)
}
Comment on lines +101 to +125
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix typo in error message.

Line 108 contains a typo: "Bas request" should be "Bad request".

Apply this diff:

 		response := Response{
 			Success: false,
-			Error:   "Bas request",
+			Error:   "Bad request",
 			Message: err.Error(),
 			Code:    http.StatusBadRequest,
 		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// createUser handles POST /users
func createUser(c *gin.Context) {
var user User
if err := c.ShouldBindJSON(&user); err != nil {
response := Response{
Success: false,
Error: "Bas request",
Message: err.Error(),
Code: http.StatusBadRequest,
}
c.IndentedJSON(http.StatusBadRequest, response)
return
}
user.ID = nextID
users = append(users, user)
nextID++
response := Response{
Success: true,
Data: user,
}
c.IndentedJSON(http.StatusCreated, response)
}
// createUser handles POST /users
func createUser(c *gin.Context) {
var user User
if err := c.ShouldBindJSON(&user); err != nil {
response := Response{
Success: false,
Error: "Bad request",
Message: err.Error(),
Code: http.StatusBadRequest,
}
c.IndentedJSON(http.StatusBadRequest, response)
return
}
user.ID = nextID
users = append(users, user)
nextID++
response := Response{
Success: true,
Data: user,
}
c.IndentedJSON(http.StatusCreated, response)
}
🤖 Prompt for AI Agents
In packages/gin/challenge-1-basic-routing/submissions/AlexO-85/solution.go
around lines 101 to 125, there's a typo in the error response string "Bas
request" at line 108; update that string to "Bad request" so the Response.Error
field contains the correct message, then run gofmt/quick vet to ensure no other
changes are needed.


// updateUser handles PUT /users/:id
func updateUser(c *gin.Context) {
idStr := c.Param("id")
// Handle invalid ID format
id, err := strconv.Atoi(idStr)
if err != nil {
response := Response{
Success: false,
Error: "User ID format is wrong",
Message: err.Error(),
Code: http.StatusBadRequest,
}
c.IndentedJSON(http.StatusBadRequest, response)
return
}

var newUser User

if err := c.ShouldBindJSON(&newUser); err != nil {
response := Response{
Success: false,
Error: "Bas request",
Message: err.Error(),
Code: http.StatusBadRequest,
}
c.IndentedJSON(http.StatusBadRequest, response)
return
}

if user, _ := findUserByID(id); user != nil {
user.Name = newUser.Name
user.Email = newUser.Email
user.Age = newUser.Age

response := Response{
Success: true,
Data: user,
}
c.IndentedJSON(http.StatusOK, response)
return
}

response := Response{
Success: false,
Error: "User not found",
Code: http.StatusNotFound,
}

c.IndentedJSON(http.StatusNotFound, response)
}
Comment on lines +127 to +176
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix typo in error message.

Line 148 contains the same typo: "Bas request" should be "Bad request".

Apply this diff:

 		response := Response{
 			Success: false,
-			Error:   "Bas request",
+			Error:   "Bad request",
 			Message: err.Error(),
 			Code:    http.StatusBadRequest,
 		}
🤖 Prompt for AI Agents
packages/gin/challenge-1-basic-routing/submissions/AlexO-85/solution.go lines
127-176: the error response for JSON binding has a typo "Bas request"; update
the Response.Error string to "Bad request" (fix the typo) so the error reads
"Bad request" before returning the 400 response.


// deleteUser handles DELETE /users/:id
func deleteUser(c *gin.Context) {
idStr := c.Param("id")
// Handle invalid ID format
id, err := strconv.Atoi(idStr)
if err != nil {
response := Response{
Success: false,
Error: "User ID format is wrong",
Message: err.Error(),
Code: http.StatusBadRequest,
}
c.IndentedJSON(http.StatusBadRequest, response)
return
}

if user, i := findUserByID(id); user != nil {
response := Response{
Success: true,
Data: user,
}
c.IndentedJSON(http.StatusOK, response)

users = append(users[:i], users[i+1:]...)

return
}

response := Response{
Success: false,
Error: "User not found",
Code: http.StatusNotFound,
}

c.IndentedJSON(http.StatusNotFound, response)
}

// searchUsers handles GET /users/search?name=value
func searchUsers(c *gin.Context) {

name := strings.ToLower(c.Query("name"))

if name == "" {
response := Response{
Success: false,
Error: "Name parameter is missing",
Code: http.StatusBadRequest,
}
c.IndentedJSON(http.StatusBadRequest, response)
return
}

found := []User{}

for _, user := range users {
if strings.Contains(strings.ToLower(user.Name), name) {
found = append(found, user)
}
}

response := Response{
Success: true,
Data: found,
}
c.IndentedJSON(http.StatusOK, response)
}

// Helper function to find user by ID
func findUserByID(id int) (*User, int) {
for i := range users {
if users[i].ID == id {
return &users[i], i
}
}
return nil, -1
}
Loading