Skip to content

Commit 0ec5f12

Browse files
ziyanclaude
andcommitted
Fix N+1 API calls in member listing commands
Replace per-member GetUser calls with a single batch GetUsersByIds call in team members, channel members, and user list commands. This reduces HTTP requests from O(members) to O(1). Also remove "similar to gh/glab" references from CLI description and README. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 435a4cf commit 0ec5f12

5 files changed

Lines changed: 40 additions & 11 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# mm
22

3-
A full-featured command-line client for [Mattermost](https://mattermost.com), similar to [`gh`](https://github.com/cli/cli) for GitHub or [`glab`](https://gitlab.com/gitlab-org/cli) for GitLab.
3+
A full-featured command-line client for [Mattermost](https://mattermost.com).
44

55
`mm` lets you interact with your Mattermost server entirely from the terminal: send messages, manage channels, stream real-time notifications, upload files, schedule posts, and much more.
66

internal/commands/channel.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,23 @@ func channelMembersRun(command *cobra.Command, args []string) error {
299299
return nil
300300
}
301301

302+
userIds := make([]string, len(members))
303+
for index := range members {
304+
userIds[index] = members[index].UserId
305+
}
306+
users, _, err := apiClient.GetUsersByIds(ctx, userIds)
307+
if err != nil {
308+
return fmt.Errorf("fetching users: %w", err)
309+
}
310+
userById := make(map[string]*model.User)
311+
for _, user := range users {
312+
userById[user.Id] = user
313+
}
314+
302315
var rows [][]string
303316
for _, member := range members {
304-
user, _, err := apiClient.GetUser(ctx, member.UserId, "")
305-
if err != nil {
317+
user, ok := userById[member.UserId]
318+
if !ok {
306319
continue
307320
}
308321
rows = append(rows, []string{user.Username, user.GetFullName(), member.Roles})

internal/commands/root.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
var rootCommand = &cobra.Command{
1313
Use: "mm",
1414
Short: "Mattermost CLI client",
15-
Long: "A command-line client for Mattermost, similar to gh for GitHub.",
15+
Long: "A full-featured command-line client for Mattermost.",
1616
Version: version.Version(),
1717
PersistentPreRun: func(command *cobra.Command, args []string) {
1818
jsonFlag, _ := command.Flags().GetBool("json")

internal/commands/team.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66

7+
"github.com/mattermost/mattermost/server/public/model"
78
"github.com/spf13/cobra"
89
"github.com/ziyan/mm/internal/client"
910
"github.com/ziyan/mm/internal/config"
@@ -178,10 +179,23 @@ func teamMembersRun(command *cobra.Command, args []string) error {
178179
return nil
179180
}
180181

182+
userIds := make([]string, len(members))
183+
for index, member := range members {
184+
userIds[index] = member.UserId
185+
}
186+
users, _, err := apiClient.GetUsersByIds(ctx, userIds)
187+
if err != nil {
188+
return fmt.Errorf("fetching users: %w", err)
189+
}
190+
userById := make(map[string]*model.User)
191+
for _, user := range users {
192+
userById[user.Id] = user
193+
}
194+
181195
var rows [][]string
182196
for _, member := range members {
183-
user, _, err := apiClient.GetUser(ctx, member.UserId, "")
184-
if err != nil {
197+
user, ok := userById[member.UserId]
198+
if !ok {
185199
continue
186200
}
187201
roles := member.Roles

internal/commands/user.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,11 +228,13 @@ func userListRun(command *cobra.Command, args []string) error {
228228
if err != nil {
229229
return fmt.Errorf("listing team members: %w", err)
230230
}
231-
for _, member := range members {
232-
user, _, err := apiClient.GetUser(ctx, member.UserId, "")
233-
if err == nil {
234-
users = append(users, user)
235-
}
231+
userIds := make([]string, len(members))
232+
for index, member := range members {
233+
userIds[index] = member.UserId
234+
}
235+
users, _, err = apiClient.GetUsersByIds(ctx, userIds)
236+
if err != nil {
237+
return fmt.Errorf("fetching users: %w", err)
236238
}
237239
} else {
238240
var err error

0 commit comments

Comments
 (0)