Skip to content

Add solution for gin challenge-1-basic-routing by ItalloMangueBoy#1223

Merged
github-actions[bot] merged 2 commits intoRezaSi:mainfrom
ItalloMangueBoy:package-gin-challenge-1-basic-routing-ItalloMangueBoy
Apr 14, 2026
Merged

Add solution for gin challenge-1-basic-routing by ItalloMangueBoy#1223
github-actions[bot] merged 2 commits intoRezaSi:mainfrom
ItalloMangueBoy:package-gin-challenge-1-basic-routing-ItalloMangueBoy

Conversation

@ItalloMangueBoy
Copy link
Copy Markdown
Contributor

gin challenge-1-basic-routing Solution

Submitted by: @ItalloMangueBoy
Package: gin
Challenge: challenge-1-basic-routing

Description

This PR contains my solution for gin challenge-1-basic-routing.

Changes

  • Added solution file to packages/gin/challenge-1-basic-routing/submissions/ItalloMangueBoy/solution.go

Testing

  • Solution passes all test cases
  • Code follows Go best practices

Thank you for reviewing my submission! 🚀

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 29, 2026

Walkthrough

New Go solution file implementing a Gin-based HTTP API for user management. Defines User and Response structs, maintains an in-memory user store, and implements CRUD handlers and search functionality with input validation and error handling.

Changes

Cohort / File(s) Summary
Gin User Management API
packages/gin/challenge-1-basic-routing/submissions/ItalloMangueBoy/solution.go
Introduces User struct (ID, Name, Email, Age) and Response struct (Success, Data, Message, Error, Code). Implements HTTP handlers for GET/POST/PUT/DELETE /users routes, user search by name, input validation, and in-memory storage operations with helper functions for finding users and validating data.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding a solution for a specific gin challenge by a named contributor.
Description check ✅ Passed The description is directly related to the changeset, providing context about the challenge, the contributor, and the specific file added.
Docstring Coverage ✅ Passed Docstring coverage is 88.89% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In
`@packages/gin/challenge-1-basic-routing/submissions/ItalloMangueBoy/solution.go`:
- Around line 119-124: The HTTP status code in the validation error block is
inconsistent: when validateUser(newUser) returns an error the JSON payload sets
Code: 422 but c.JSON currently returns 400; change the c.JSON call in the if err
:= validateUser(newUser); err != nil { ... } block to use status 422 so the HTTP
response status matches the Response.Code field (keep Response, Error, Success
unchanged).
- Around line 167-192: The update handler currently lets updatedUser.ID drift
and returns the old user and wrong HTTP status on validation failure; before
validating/assigning, set updatedUser.ID = ID (or preserve existing user.ID from
findUserByID) so the path ID is preserved, change the validation response to use
HTTP 422 (c.JSON(422, ...)) when validateUser fails, ensure you write
users[index] = updatedUser and return the stored user (users[index]) in the
success response instead of the original user variable; reference
functions/vars: validateUser, findUserByID, updatedUser, users, ID, index.
- Around line 28-35: Add a package import for "sync", declare a global guard var
usersMu sync.RWMutex, and wrap all accesses to the in-memory variables users and
nextID in the appropriate locks: use usersMu.RLock()/usersMu.RUnlock() around
read-only accesses and usersMu.Lock()/usersMu.Unlock() around writes (e.g., when
appending to users or incrementing nextID in your create handler and when
modifying or deleting entries in update/delete handlers); run go test -race to
verify.
- Around line 36-55: The server is started incorrectly with r.Run("8080") in
main; change the argument to the host:port form (e.g., r.Run(":8080")) or remove
the argument to use the default so Gin calls http.ListenAndServe with a valid
address; update the call to r.Run(":8080") (or r.Run()) in main to fix the
listen address.

Comment on lines +28 to +35
// In-memory storage
var users = []User{
{ID: 1, Name: "John Doe", Email: "john@example.com", Age: 30},
{ID: 2, Name: "Jane Smith", Email: "jane@example.com", Age: 25},
{ID: 3, Name: "Bob Wilson", Email: "bob@example.com", Age: 35},
}
var nextID = 4

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Protect the in-memory store with a mutex to avoid data races.
Gin handlers run concurrently; unsynchronized access to users and nextID can cause races, duplicate IDs, or slice corruption. Introduce a sync.RWMutex and lock around reads/writes.

🔒 Suggested guard for the store
 var users = []User{
 	{ID: 1, Name: "John Doe", Email: "john@example.com", Age: 30},
 	{ID: 2, Name: "Jane Smith", Email: "jane@example.com", Age: 25},
 	{ID: 3, Name: "Bob Wilson", Email: "bob@example.com", Age: 35},
 }
 var nextID = 4
+var usersMu sync.RWMutex

Also add sync to imports and use usersMu.RLock()/usersMu.Lock() in handlers. Please verify with the Go race detector locally (e.g., go test -race ./...).

🤖 Prompt for AI Agents
In
`@packages/gin/challenge-1-basic-routing/submissions/ItalloMangueBoy/solution.go`
around lines 28 - 35, Add a package import for "sync", declare a global guard
var usersMu sync.RWMutex, and wrap all accesses to the in-memory variables users
and nextID in the appropriate locks: use usersMu.RLock()/usersMu.RUnlock()
around read-only accesses and usersMu.Lock()/usersMu.Unlock() around writes
(e.g., when appending to users or incrementing nextID in your create handler and
when modifying or deleting entries in update/delete handlers); run go test -race
to verify.

Comment on lines +36 to +55
func main() {
// TODO: Create Gin router
r := gin.Default()

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

// TODO: Start server on port 8080
r.Run("8080")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

Gin Go framework Engine Run method address format ":8080" port

💡 Result:

In Gin, engine.Run(addr ...string) is just a convenience wrapper around Go’s http.ListenAndServe(addr, handler)—so the addr string uses Go’s normal host:port syntax. [1]

  • r.Run(":8080") means listen on port 8080 on all local interfaces (wildcard bind). In Go terms: if the host part is empty (e.g. ":8080"), it listens on all available IPs. [2]
  • r.Run("127.0.0.1:8080") or r.Run("localhost:8080") means listen only on the loopback interface (only reachable from the same machine).
  • r.Run() (no args) defaults to 0.0.0.0:8080 (and Gin notes Windows may show it as localhost:8080). [3]

Sources:
[1] https://pkg.go.dev/github.com/gin-gonic/gin#Engine.Run
[2] https://docs-go.hexacode.org/pkg/net/#Listen
[3] https://github.com/gin-gonic/gin (README “Your First Gin Application” section)


Use ":8080" when starting Gin.
r.Run("8080") fails because Gin's Run() wraps Go's http.ListenAndServe(), which requires host:port format. Passing just "8080" is invalid syntax. Use ":8080" to listen on port 8080 on all interfaces, or call r.Run() with no arguments to default to 0.0.0.0:8080.

✅ Suggested fix
-	r.Run("8080")
+	r.Run(":8080")
📝 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
func main() {
// TODO: Create Gin router
r := gin.Default()
// TODO: Setup routes
// GET /users - Get all users
r.GET("/users", getAllUsers)
// GET /users/:id - Get user by ID
r.GET("/users/:id", getUserByID)
// POST /users - Create new user
r.POST("/users", createUser)
// PUT /users/:id - Update user
r.PUT("/users/:id", updateUser)
// DELETE /users/:id - Delete user
r.DELETE("/users/:id", deleteUser)
// GET /users/search - Search users by name
r.GET("/users/search", searchUsers)
// TODO: Start server on port 8080
r.Run("8080")
func main() {
// TODO: Create Gin router
r := gin.Default()
// TODO: Setup routes
// GET /users - Get all users
r.GET("/users", getAllUsers)
// GET /users/:id - Get user by ID
r.GET("/users/:id", getUserByID)
// POST /users - Create new user
r.POST("/users", createUser)
// PUT /users/:id - Update user
r.PUT("/users/:id", updateUser)
// DELETE /users/:id - Delete user
r.DELETE("/users/:id", deleteUser)
// GET /users/search - Search users by name
r.GET("/users/search", searchUsers)
// TODO: Start server on port 8080
r.Run(":8080")
}
🤖 Prompt for AI Agents
In
`@packages/gin/challenge-1-basic-routing/submissions/ItalloMangueBoy/solution.go`
around lines 36 - 55, The server is started incorrectly with r.Run("8080") in
main; change the argument to the host:port form (e.g., r.Run(":8080")) or remove
the argument to use the default so Gin calls http.ListenAndServe with a valid
address; update the call to r.Run(":8080") (or r.Run()) in main to fix the
listen address.

Comment on lines +119 to +124
if err := validateUser(newUser); err != nil {
c.JSON(400, Response{
Success: false,
Error: err.Error(),
Code: 422,
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

HTTP status should match the 422 response code.
Right now the validation error returns HTTP 400 while the payload says 422.

✅ Suggested fix
-		c.JSON(400, Response{
+		c.JSON(422, Response{
 			Success: false,
 			Error:   err.Error(),
 			Code:    422,
 		})
📝 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
if err := validateUser(newUser); err != nil {
c.JSON(400, Response{
Success: false,
Error: err.Error(),
Code: 422,
})
if err := validateUser(newUser); err != nil {
c.JSON(422, Response{
Success: false,
Error: err.Error(),
Code: 422,
})
🤖 Prompt for AI Agents
In
`@packages/gin/challenge-1-basic-routing/submissions/ItalloMangueBoy/solution.go`
around lines 119 - 124, The HTTP status code in the validation error block is
inconsistent: when validateUser(newUser) returns an error the JSON payload sets
Code: 422 but c.JSON currently returns 400; change the c.JSON call in the if err
:= validateUser(newUser); err != nil { ... } block to use status 422 so the HTTP
response status matches the Response.Code field (keep Response, Error, Success
unchanged).

Comment on lines +167 to +192
if err := validateUser(updatedUser); err != nil {
c.JSON(400, Response{
Success: false,
Error: err.Error(),
Code: 422,
})
return
}

user, index := findUserByID(ID)
if index == -1 {
c.JSON(404, Response{
Success: false,
Error: "User not found",
Code: 404,
})
return
}

users[index] = updatedUser

c.JSON(200, Response{
Success: true,
Data: user,
Code: 200,
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Preserve path ID on update and return the updated resource.
updatedUser.ID can drift (or be zero), and the response should reflect the final stored user. Also align validation error status with 422 here.

✅ Suggested fix
-	if err := validateUser(updatedUser); err != nil {
-		c.JSON(400, Response{
+	if err := validateUser(updatedUser); err != nil {
+		c.JSON(422, Response{
 			Success: false,
 			Error:   err.Error(),
 			Code:    422,
 		})
 		return
 	}
@@
-	users[index] = updatedUser
+	updatedUser.ID = ID
+	users[index] = updatedUser
 
 	c.JSON(200, Response{
 		Success: true,
-		Data:    user,
+		Data:    users[index],
 		Code:    200,
 	})
🤖 Prompt for AI Agents
In
`@packages/gin/challenge-1-basic-routing/submissions/ItalloMangueBoy/solution.go`
around lines 167 - 192, The update handler currently lets updatedUser.ID drift
and returns the old user and wrong HTTP status on validation failure; before
validating/assigning, set updatedUser.ID = ID (or preserve existing user.ID from
findUserByID) so the path ID is preserved, change the validation response to use
HTTP 422 (c.JSON(422, ...)) when validateUser fails, ensure you write
users[index] = updatedUser and return the stored user (users[index]) in the
success response instead of the original user variable; reference
functions/vars: validateUser, findUserByID, updatedUser, users, ID, index.

@github-actions github-actions bot merged commit c6cc693 into RezaSi:main Apr 14, 2026
6 checks passed
@github-actions
Copy link
Copy Markdown

🎉 Auto-merged!

This PR was automatically merged after 2 days with all checks passing.

Thank you for your contribution, @ItalloMangueBoy!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants