src/server/pkg/collection/collection.go
func (c *readonlyCollection) List(val proto.Message, opts *Options, f func(string) error) error {
	if err := watch.CheckType(c.template, val); err != nil {
		return err
	}
	return c.list(c.prefix, &c.limit, opts, func(kv *mvccpb.KeyValue) error {
		if err := proto.Unmarshal(kv.Value, val); err != nil {
			return err
		}
		return f(strings.TrimPrefix(string(kv.Key), c.prefix))
	})
}
func (c *readonlyCollection) List(val proto.Message, opts *Options, f func(string) error) error {
	if err := watch.CheckType(c.template, val); err != nil {
		return err
	}
	return c.list(c.prefix, &c.limit, opts, func(kv *mvccpb.KeyValue) error {
		if err := proto.Unmarshal(kv.Value, val); err != nil {
			return err
		}
		return f(strings.TrimPrefix(string(kv.Key), c.prefix))
	})
}
// List returns objects sorted based on the options passed in. f will be called with each key, val will contain the
// corresponding value. Val is not an argument to f because that would require
// f to perform a cast before it could be used.
// You can break out of iteration by returning errutil.ErrBreak.