英文:
getting error message along with result in go api
问题
我有一个API中的路由,可以通过roles
获取用户。在这个路由中,如果我输入用户的名称,我将得到分配给他/她的所有roles
。但问题是它只返回第一个结果。如果该角色存在于另一个对象中,则不会显示。所以我在return
行上加了注释,一切都正常工作,但是除了结果之外,我还得到了错误消息:"user not found"
。你们能告诉我我犯了什么错误吗?
谢谢。
路由 -
GET("/users/:username", controllers.GetUserByRole)
控制器 -
func GetUserByRole(c *gin.Context) {
paramId := c.Param("username")
.............
.............
.............
var newUsers []models.User
iter := client.Collection("users").Documents(ctx)
for {
doc, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatalf("Failed to iterate: %v", err)
}
var tempUsers models.User
if err := doc.DataTo(&tempUsers); err != nil {
break
}
newUsers = append(newUsers, tempUsers)
}
for _, a := range newUsers {
for _, element := range a.Roles{
if element == paramId {
c.IndentedJSON(http.StatusOK, a)
return //如果我注释掉这一行,我会得到消息"user not found"以及结果
}
}
}
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "user not found"})
}
URL: http://localhost:3000/users/Analyst
应该返回的响应是:
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"roles": ["Developer", "Analyst"]
},
{
"id": 3,
"name": "Clementine Bauch",
"username": "Samantha",
"roles": ["Manger", "Analyst"]
}
但我得到的是这样的(只有第一个匹配的):
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"roles": ["Developer", "Analyst"]
}
如果我注释掉return
行,那么响应是(期望的结果+错误消息):
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"roles": ["Developer", "Analyst"]
},
{
"id": 3,
"name": "Clementine Bauch",
"username": "Samantha",
"roles": ["Manger", "Analyst"]
},
{
"message": "album not found"
}
完整的API响应 -
[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"roles": ["Developer", "Analyst"]
},
{
"id": 2,
"name": "Ervin Howell",
"username": "Antonette",
"roles": ["Assistant"]
},
{
"id": 3,
"name": "Clementine Bauch",
"username": "Samantha",
"roles": ["Manger", "Analyst"]
}
]
英文:
I have one route in API where I can get users with roles
. In this route, if I put the name of the user then I will get all the roles
assigned to him/her. But the problem is that it returns only the first result. If that role is present in another object then it is not getting displayed. So I comment on the return
line and everything works fine but along with the result, I am getting the error message:"user not found"
Can you guys please tell me what mistake I am doing?
Thank you.
Route -
GET("/users/:username", controllers.GetUserByRole)
Controller -
func GetUserByRole(c *gin.Context) {
paramId := c.Param("username")
.............
.............
.............
var newUsers []models.User
iter := client.Collection("users").Documents(ctx)
for {
doc, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatalf("Failed to iterate: %v", err)
}
var tempUsers models.User
if err := doc.DataTo(&tempUsers); err != nil {
break
}
newUsers = append(newUsers, tempUsers)
}
for _, a := range newUsers {
for _, element := range a.Roles{
if element == paramId {
c.IndentedJSON(http.StatusOK, a)
return //if I comment this line line then I geting message `"user not found"` along with results
}
}
}
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "user not found"})
}
URL: http://localhost:3000/users/Analyst
Response Should be:
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"roles": ["Developer", "Analyst"],
},
{
"id": 3,
"name": "Clementine Bauch",
"username": "Samantha",
"roles": ["Manger", "Analyst"],
}
but I am getting like this (only the first matching one):
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"roles": ["Developer", "Analyst"],
}
If I comment the return
line then response is (desired result + error message):
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"roles": ["Developer", "Analyst"],
},
{
"id": 3,
"name": "Clementine Bauch",
"username": "Samantha",
"roles": ["Manger", "Analyst"],
}{
"message": "album not found"
}
Complete API response -
[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"roles": ["Developer", "Analyst"],
},
{
"id": 2,
"name": "Ervin Howell",
"username": "Antonette",
"roles": ["Assistant"],,
},
{
"id": 3,
"name": "Clementine Bauch",
"username": "Samantha",
"roles": ["Manger", "Analyst"],
}
]
</details>
# 答案1
**得分**: 2
你可以这样做:
```go
var userList []models.User
for _, a := range newUsers {
for _, element := range a.AssignedTo {
if element == paramId {
userList = append(userList, a)
}
}
}
if len(userList) == 0 {
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "用户未找到"})
return
}
c.IndentedJSON(http.StatusOK, userList)
这段代码的作用是根据指定的参数ID筛选出符合条件的用户,并将结果以JSON格式返回。如果未找到符合条件的用户,将返回一个包含错误信息的JSON响应。
英文:
You can do like this
var userList []models.User
for _, a := range newUsers {
for _, element := range a.AssignedTo {
if element == paramId {
userList = append(userList, a)
}
}
}
if len(userList) == 0 {
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "user not found"})
return
}
c.IndentedJSON(http.StatusOK, userList)
答案2
得分: 0
看起来你的return语句在for循环内部,所以它找到第一个值后立即返回。当你将其注释掉时,函数没有返回,所以它成功完成然后打印错误消息。将return语句移到两个for循环之外,问题就会解决。此外,通过添加一个errorflag来发送错误消息也是一种解决方法。也建议采用Manjeet Thakur的替代解决方案。
func GetUserByRole(c *gin.Context) {
paramId := c.Param("username")
.............
.............
.............
var newUsers []models.User
iter := client.Collection("users").Documents(ctx)
for {
doc, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatalf("Failed to iterate: %v", err)
}
var tempUsers models.User
if err := doc.DataTo(&tempUsers); err != nil {
break
}
newUsers = append(newUsers, tempUsers)
}
var errorflag := 1
for _, a := range newUsers {
for _, element := range a.AssignedTo {
if element == paramId {
c.IndentedJSON(http.StatusOK, a)
errorflag := 0
//如果我注释掉这一行,我会得到`"user not found"`的消息以及结果
}
}
}
if errorflag {
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "user not found"})
}
return
}
英文:
Looks like your return statement is inside your for loop, so it find the first value and immediately returns. Your function doesn't return when you comment it out so it completes successfully and then prints the error message. Move the return statement outside both for loops and it should be fine. Also, add logic for sending the error message by having an errorflag. The alternative solution from Manjeet Thakur is also recommended.
func GetUserByRole(c *gin.Context) {
paramId := c.Param("username")
.............
.............
.............
var newUsers []models.User
iter := client.Collection("users").Documents(ctx)
for {
doc, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatalf("Failed to iterate: %v", err)
}
var tempUsers models.User
if err := doc.DataTo(&tempUsers); err != nil {
break
}
newUsers = append(newUsers, tempUsers)
}
var errorflag := 1
for _, a := range newUsers {
for _, element := range a.AssignedTo {
if element == paramId {
c.IndentedJSON(http.StatusOK, a)
errorflag := 0
//if I comment this line line then I geting message `"user not found"` along with results
}
}
}
if errorflag{
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "user not found"})
}
return
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论