Parse openai response
Content-Encoding
基于openai封装了一个简单的translate api。目的一是练习go gin;二是后续支持翻译本blog的文章为其他语言。基本实现思路为将请求proxy到openai rest, 再修改返回后的response作为最终结果。
作为一个从spring过来用go写rest api的人,发现go gin并没有spring那么smart或者说high level。比如说response需要unmarshal为struct再使用。无论content-encoding是什么, spring可以无感知的帮你deserialize为对应的class。但在gin里面你需要根据content-encoding采用不同的decode方法。我几乎从来没有关心过content-encoding, accept-encoding这些特殊的response, request头。
说回我遇到的问题。在decode http.response的过程中报错:invalid character '!' looking for beginning of value。经查发现这是由于返回的response非文本导致的,比如可能使用了压缩。这样直接decode就会有问题,所以需要先解压再unmarshal,而openai的response就是采用br和gzip两种压缩方式。最终将代码修改为根据content-encoding采取不同的decode方法解决了问题。
func parseOpenAiResponse(resp *http.Response) (OpenAiResponse, error) {
var reader io.Reader
switch resp.Header.Get("Content-Encoding") {
case "br":
brReader := brotli.NewReader(resp.Body)
reader = brReader
case "gzip":
reader, _ = gzip.NewReader(resp.Body)
default:
// Handle other encodings or no encoding here, if needed.
reader = resp.Body
}
_bytes, _ := io.ReadAll(reader)
var ret OpenAiResponse
err := json.Unmarshal(_bytes, &ret)
return ret, err
}