Nombres clave JSON en minúsculas con JSON Marshal en Go

175

Deseo utilizar el "encoding/json"paquete para ordenar una estructura declarada en uno de los paquetes importados de mi aplicación.

P.ej.:

type T struct {
    Foo int
}

Como se importa, todos los campos disponibles (exportados) en la estructura comienzan con una letra mayúscula. Pero deseo tener nombres clave en minúsculas:

out, err := json.Marshal(&T{Foo: 42})

resultará en

{"Foo": 42}

pero deseo conseguir

{"foo": 42}

¿Es posible solucionar el problema de alguna manera fácil?

ANisus
fuente
55
@Zippoxer: Diría: una clave en un protocolo de comunicación cliente / servidor estrictamente definido con letras minúsculas. Bueno, en mi caso no importa ya que yo mismo he definido el protocolo ... ¿pero al menos en teoría? Pero, sé que es principalmente solo yo pasando demasiado tiempo en un pequeño detalle tonto.
ANisus
No te disculpes. No eres el tonto, el lenguaje que no acepta la especificación completa de json es el tonto (aunque el problema se resuelve fácilmente, como se muestra a continuación).
Jehan
@ ANisus: leí mal su pregunta sobre los nombres de clave de estructura, no los nombres de clave JSON. Retiró el voto.
Flimzy

Respuestas:

266

Echa un vistazo a los documentos para codificar / json.Marshal . Discute el uso de etiquetas de campo de estructura para determinar cómo se formatea el json generado.

Por ejemplo:

type T struct {
    FieldA int    `json:"field_a"`
    FieldB string `json:"field_b,omitempty"`
}

Esto generará JSON de la siguiente manera:

{
    "field_a": 1234,
    "field_b": "foobar"
}
jimt
fuente
8
Etiquetas de campo? Oh mi ... Me perdí toda esta parte al buscar en los documentos. Estaba buscando banderas, funciones o alguna otra configuración. Bueno, esta es la respuesta exacta que estaba buscando. Y además, tengo un nuevo concepto de Go para aprender: etiquetas de campo :)
ANisus
Son bastante útiles. Puede acceder a ellos en tiempo de ejecución a través del reflectpaquete.
jimt
Sí, cuando trabajo con la reflexión, veo que tener una manera de agregar metadatos a un campo puede ser algo maravilloso. Por cierto, acabo de probar la respuesta. Funciona de maravilla.
ANisus
55
Acabo de empezar a maldecir el lenguaje go: qué estúpido es esto, ¿por qué harían los campos con letras minúsculas en el JSON generado, etc.? Incluso salté y le expliqué a mi novia por qué estoy tan emocionada: D Es tan genial :)))
nyxz
11
¡Asegúrese de que no haya espacio entre los dos puntos y la primera comilla de la etiqueta! Usar en json:"some_tag"lugar de json: "some_tag". Me mordió esto por un tiempo.
David Morales
8

Puede crear su propia estructura con las claves que desea exportar y asignarles las etiquetas json apropiadas para los nombres en minúsculas. Luego puede copiar la estructura deseada en la suya antes de codificarla como JSON. O si no quiere molestarse en hacer una estructura local, probablemente podría hacer una map[string]interface{}y codificar eso.

Lily Ballard
fuente
Lo tonto es que el otro paquete (que contiene los tipos) también es mío. Pero sí, probablemente me he quedado mirando ciegamente el hecho de que debe ser una estructura. Usar a map[string]interface{}funcionaría siempre que no termine con objetos / estructuras anidadas
ANisus
1
@ ANisus: Oh, mi respuesta se basó en que no tienes el control de la definición de la estructura. La respuesta de Jimt es definitivamente lo que quieres.
Lily Ballard
Sí, no estaba claro si era o no un paquete externo o no. Pero su respuesta sigue siendo relevante y útil en los casos en que no controla las definiciones.
ANisus