Golang – Ristretto缓存返回base64

huangapple go评论95阅读模式
英文:

Golang - Ristretto Cache returning base 64

问题

我在使用ristretto缓存时遇到了问题。实际上,我有一个小的API,应该以JSON格式返回存储在ristretto缓存中的值。

问题是,当我调用我的函数时,返回的是以base64编码的JSON,我找不到解码的方法。

这是我的代码:

  • 第一部分:初始化ristretto缓存的代码:
func InitCache() {
	var err error
	ristrettoCache, err = ristretto.NewCache(&ristretto.Config{
		NumCounters: 3000,
		MaxCost: 1e6,
		BufferItems: 64,
	})
	if err != nil {
		panic(err)
	}
}

第二部分:将值放入缓存:

for _, t := range listTokensFromDB {
	b, err := json.Marshal(t)
	if err != nil {
		fmt.Println(err)
	}
	ristrettoCache.Set(t.Symbol, b, 1)
}

第三部分:从缓存中获取值:

func getTokenInfo(w http.ResponseWriter, r *http.Request){
	vars := mux.Vars(r)
	key := vars["chain"]+vars["symbol"]
	value, found := ristrettoCache.Get(key)
	if !found {
		return
	}
	json.NewEncoder(w).Encode(value)
}

当我调用我的API时,得到的结果是:

"eyJTeW1ib2wiOiJic2NDUllQVE8iLCJBZGRyIjoiMHgyQmNBMUFlM0U1MjQ0NzMyM0IzRWE0NzA4QTNkMTg1ODRDYWY4NWE3IiwiTHBzIjpbeyJTeW1ib2xUb2tlbiI6IkZFRyIsIlRva2VuQWRkciI6IjB4YWNGQzk1NTg1RDgwQWI2MmY2N0ExNEM1NjZDMWI3YTQ5RmU5MTE2NyIsIkxwQWRkciI6IjB4NDU5ZTJlMjQ4NGNlMDU2MWRmNTJiYzFlNjkxMzkyNDA2M2JhZDM5MCJ9LHsiU3ltYm9sVG9rZW4iOiJmQk5CIiwiVG9rZW5BZGRyIjoiMHg4N2IxQWNjRTZhMTk1OEU1MjIyMzNBNzM3MzEzQzA4NjU1MWE1Yzc2IiwiTHBBZGRyIjoiMHg3OGM2NzkzZGMxMDY1OWZlN2U0YWJhMTQwMmI5M2Y2ODljOGY0YzI3In1dfQ=="

但我想要的是base64解码后的版本...

如果我在将其插入缓存时将值b更改为字符串,像这样:

for _, t := range listTokensFromDB {
	b, err := json.Marshal(t)
	if err != nil {
		fmt.Println(err)
	}

	ristrettoCache.Set(t.Symbol, string(b), 1)
}

当我得到响应时,我得到了字符串化的JSON,像这样:
"{"Symbol":"bscCRYPTO","Addr":"0x2BcA1Ae3E52447323B..."

我找不到一种方法来解析这个字符串 :/

有人知道如何获取真正的JSON吗?

提前谢谢你,祝你有个愉快的一天!

英文:

I am encountering a problem while using ristretto cache. Indeed, i have a little api that should return me a value stored in my ristretto cache as json.

The problem is that when i call my function, the return is the json encoded in base64 and i just can't find the way to decode it.

Here is the code i have:

  • Part 1: the code for initializing my ristretto cache:
func InitCache() {
	var err error
	ristrettoCache, err = ristretto.NewCache(&ristretto.Config{
		NumCounters: 3000,
		MaxCost: 1e6,
		BufferItems: 64,
	})
	if err != nil {
		panic(err)
	}
}

Part 2: Putting my values in cache:

for _, t := range listTokensFromDB {
	b, err := json.Marshal(t)
	if err != nil {
		fmt.Println(err)
	}
	ristrettoCache.Set(t.Symbol, b, 1)
}

Part 3: getting the value from cache

func getTokenInfo(w http.ResponseWriter, r *http.Request){
	vars := mux.Vars(r)
	key := vars["chain"]+vars["symbol"]
	value, found := ristrettoCache.Get(key)
	if !found {
		return
	}
	json.NewEncoder(w).Encode(value)
}

The result i have when i make a call to my api is:

"eyJTeW1ib2wiOiJic2NDUllQVE8iLCJBZGRyIjoiMHgyQmNBMUFlM0U1MjQ0NzMyM0IzRWE0NzA4QTNkMTg1ODRDYWY4NWE3IiwiTHBzIjpbeyJTeW1ib2xUb2tlbiI6IkZFRyIsIlRva2VuQWRkciI6IjB4YWNGQzk1NTg1RDgwQWI2MmY2N0ExNEM1NjZDMWI3YTQ5RmU5MTE2NyIsIkxwQWRkciI6IjB4NDU5ZTJlMjQ4NGNlMDU2MWRmNTJiYzFlNjkxMzkyNDA2M2JhZDM5MCJ9LHsiU3ltYm9sVG9rZW4iOiJmQk5CIiwiVG9rZW5BZGRyIjoiMHg4N2IxQWNjRTZhMTk1OEU1MjIyMzNBNzM3MzEzQzA4NjU1MWE1Yzc2IiwiTHBBZGRyIjoiMHg3OGM2NzkzZGMxMDY1OWZlN2U0YWJhMTQwMmI5M2Y2ODljOGY0YzI3In1dfQ=="

But i want the base64 decoded version...

If I change the value b to be string when i insert it in cache like so:

for _, t := range listTokensFromDB {
		b, err := json.Marshal(t)
		if err != nil {
			fmt.Println(err)
		}

		ristrettoCache.Set(t.Symbol, string(b), 1)
	}

When i get the response, i get the stringified json like this:
"{"Symbol":"bscCRYPTO","Addr":"0x2BcA1Ae3E52447323B..."

And i can't find a way to get out of this string :/

Anyone would know how i could get the real json please?

Thank you in advance and i wish u a good day!

答案1

得分: 0

从我的评论中,我指的是,在这一行中,value 很可能是 []byte 类型(或者 []uint8 - 这是相同的东西)

value, found := ristrettoCache.Get(key)

[]byte 编码为 JSON 时,输出将隐式地进行 base64 编码 - 因为 JSON 是基于文本的。

json.NewEncoder(w).Encode(value) // <- value 是 []byte 类型

检查你发布的 base64(https://play.golang.org/p/NAVS4qRfDM2),底层的二进制字节已经在 JSON 中编码 - 因此不需要额外的 json.Encode

只需在处理程序中输出原始字节,并将内容类型设置为 application/json

func getTokenInfo(w http.ResponseWriter, r *http.Request){
    vars := mux.Vars(r)
    key := vars["chain"]+vars["symbol"]
    value, found := ristrettoCache.Get(key)
    if !found {
        return
    }

    // json.NewEncoder(w).Encode(value) // 不要这样做

    w.Header().Set("Content-Type", "application/json")

    if bs, ok := value.([]byte); ok {
        _, err := w.Write(bs) // 原始字节(已经在 JSON 中编码)

        // 检查 'err'
    } else {
        // 错误:接口{} 后面的类型不符合预期
    }
}
英文:

From my comments, I meant, in this line, value is most likely of type []byte (or []uint8 - which is the same thing)

value, found := ristrettoCache.Get(key)

JSON encoding a []byte will implicitly base64 the output - since JSON is text-based.

json.NewEncoder(w).Encode(value) // <- value is of type []byte

Inspecting the base64 you posted (https://play.golang.org/p/NAVS4qRfDM2) the underlying binary-bytes are already encoded in JSON - so no extra json.Encode is needed.

Just output the raw-bytes in your handler - and set the content-type to application/json:

func getTokenInfo(w http.ResponseWriter, r *http.Request){
    vars := mux.Vars(r)
    key := vars["chain"]+vars["symbol"]
    value, found := ristrettoCache.Get(key)
    if !found {
        return
    }

    // json.NewEncoder(w).Encode(value) // not this

    w.Header().Set("Content-Type", "application/json")

    if bs, ok := value.([]byte); ok {
        _, err := w.Write(bs) //raw bytes (already encoded in JSON)

        // check 'err'
    } else {
        // error unexpected type behind interface{}
    }
}

huangapple
  • 本文由 发表于 2021年11月12日 04:00:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/69934224.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定