Estoy desarrollando un cliente API donde necesito codificar una carga JSON a pedido y decodificar un cuerpo JSON a partir de la respuesta.
He leído el código fuente de varias bibliotecas y, por lo que he visto, tengo básicamente dos posibilidades para codificar y decodificar una cadena JSON.
Use json.Unmarshal
pasar toda la cadena de respuesta
data, err := ioutil.ReadAll(resp.Body)
if err == nil && data != nil {
err = json.Unmarshal(data, value)
}
o usando json.NewDecoder.Decode
err = json.NewDecoder(resp.Body).Decode(value)
En mi caso, cuando se trata de respuestas HTTP que se implementan io.Reader
, la segunda versión parece requerir menos código, pero como he visto ambas, me pregunto si hay alguna preferencia si debería usar una solución en lugar de la otra.
Además, la respuesta aceptada de esta pregunta dice
Por favor, use en
json.Decoder
lugar dejson.Unmarshal
.
pero no mencionó la razón. ¿Debo realmente evitar usar json.Unmarshal
?
ioutil.ReadAll
es algo incorrecto. No está relacionado con su objetivo, pero requiere que tenga suficiente memoria contigua para almacenar lo que pueda venir, incluso si los últimos 20 TB de respuesta son posteriores al último en su JSON.}
io.LimitReader
para evitar eso.Respuestas:
Realmente depende de cuál sea su aporte. Si observa la implementación del
Decode
método dejson.Decoder
, almacena el valor JSON completo en la memoria antes de descomponerlo en un valor Go. Por lo tanto, en la mayoría de los casos no será más eficiente en la memoria (aunque esto podría cambiar fácilmente en una versión futura del idioma).Así que una mejor regla general es esta:
json.Decoder
si sus datos provienen de unaio.Reader
secuencia, o si necesita decodificar múltiples valores de una secuencia de datos.json.Unmarshal
si ya tiene los datos JSON en la memoria.Para el caso de leer desde una solicitud HTTP, elegiría
json.Decoder
ya que obviamente está leyendo desde una secuencia.fuente
Buffered
método está ahí para permitirle ver los datos adicionales que se leyeron en el búfer interno después del valor.