Nomes de chave JSON minúsculos com JSON Marshal no Go

175

Desejo usar o "encoding/json"pacote para organizar uma estrutura declarada em um dos pacotes importados do meu aplicativo.

Por exemplo.:

type T struct {
    Foo int
}

Como é importado, todos os campos disponíveis (exportados) na estrutura começam com uma letra maiúscula. Mas desejo ter nomes-chave em minúsculas:

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

vai resultar em

{"Foo": 42}

mas eu quero conseguir

{"foo": 42}

É possível contornar o problema de alguma maneira fácil?

ANisus
fonte
5
@Zippoxer: eu diria: uma chave em um protocolo de comunicação cliente / servidor estritamente definido para letras minúsculas. Bem, no meu caso, não importa, pois eu mesmo defini o protocolo ... mas, pelo menos em teoria? Mas sei que sou principalmente eu que gasto muito tempo com um pequeno detalhe bobo.
ANisus
Não peça desculpas. Você não é o bobo, o idioma que não aceita a especificação completa do json é o bobo (embora o problema seja facilmente resolvido, como abaixo).
Jehan
@ ANisus: Eu interpretei mal sua pergunta sobre nomes de chaves struct, não nomes de chaves JSON. Retirou a votação.
Flimzy

Respostas:

265

Dê uma olhada nos documentos para codificação / json.Marshal . Ele discute o uso de tags de campo struct para determinar como o json gerado é formatado.

Por exemplo:

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

Isso irá gerar JSON da seguinte maneira:

{
    "field_a": 1234,
    "field_b": "foobar"
}
jimt
fonte
8
Tags de campo? Oh meu Deus. Eu perdi essa parte inteira ao pesquisar nos documentos. Eu estava procurando sinalizadores, funções ou outras configurações. Bem, esta é a resposta exata que eu estava procurando! Além disso, eu tenho um novo conceito Go para aprender sobre: ​​tags de campo :) #
311 ANisus
Eles são bastante úteis. Você pode acessá-los em tempo de execução através do reflectpacote.
jimt
Sim, ao trabalhar com reflexão, vejo como ter uma maneira de adicionar metadados a um campo pode ser uma coisa maravilhosa! Btw, apenas tentei a resposta. Funciona como um encanto.
ANisus
5
Eu apenas comecei a amaldiçoar a linguagem "go" - como isso é estúpido, por que eles criariam os campos com letras minúsculas no JSON gerado etc etc? Eu até pulou e explicou a minha namorada por isso que estou tão animado: D É tão legal :)))
nyxz
11
Verifique se não há espaço entre os dois pontos e a primeira aspa da tag! Use em json:"some_tag"vez de json: "some_tag". Eu fiquei com isso por um tempo.
David Morales
8

Você pode criar sua própria estrutura com as chaves que deseja exportar e fornecer a elas as tags json apropriadas para nomes em minúsculas. Em seguida, você pode copiar a estrutura desejada na sua antes de codificá-la como JSON. Ou, se você não quiser se preocupar em criar uma estrutura local, provavelmente poderá criar map[string]interface{}e codificar isso.

Lily Ballard
fonte
O mais bobo é que o outro pacote (contendo os tipos) também é meu. Mas sim, provavelmente olhei cegamente para o fato de que deve ser uma estrutura. Usando um map[string]interface{}iria trabalhar enquanto eu não acabar com aninhados objetos / estruturas
ANisus
1
@ ANisus: Oh, minha resposta foi baseada em você não estar no controle da definição da estrutura. A resposta de Jimt é definitivamente o que você deseja.
Lily Ballard
Sim, não estava claro se era ou não um pacote externo. Mas sua resposta ainda é relevante e útil nos casos em que você não controla as definições.
ANisus