Skip to content

Instantly share code, notes, and snippets.

@Rican7
Last active November 27, 2023 07:10
Show Gist options
  • Save Rican7/39a3dc10c1499384ca91 to your computer and use it in GitHub Desktop.
Save Rican7/39a3dc10c1499384ca91 to your computer and use it in GitHub Desktop.
Marshal JSON in Golang using common lower-snake-case object key conventions
package main
import (
"bytes"
"encoding/json"
"fmt"
"regexp"
"time"
)
// Regexp definitions
var keyMatchRegex = regexp.MustCompile(`\"(\w+)\":`)
var wordBarrierRegex = regexp.MustCompile(`(\w)([A-Z])`)
type conventionalMarshaller struct {
Value interface{}
}
func (c conventionalMarshaller) MarshalJSON() ([]byte, error) {
marshalled, err := json.Marshal(c.Value)
converted := keyMatchRegex.ReplaceAllFunc(
marshalled,
func(match []byte) []byte {
return bytes.ToLower(wordBarrierRegex.ReplaceAll(
match,
[]byte(`${1}_${2}`),
))
},
)
return converted, err
}
type exampleModel struct {
Title string
Description string
CreatedAt time.Time
UpdatedAt time.Time
IsActive bool
}
func main() {
model := exampleModel{
Title: "Example Title",
Description: "whatever",
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
IsActive: true,
}
encoded, _ := json.MarshalIndent(conventionalMarshaller{model}, "", " ")
fmt.Println(string(encoded))
}
@Rican7
Copy link
Author

Rican7 commented Jan 16, 2019

Soooo, I know its been 3+ years and all, but I've turned this kind of behavior into a proper package:
https://github.com/Rican7/conjson

It incorporates both snake_case and camelCase transformations, among others. 😃

Thanks for the comments, suggestions, and forks on this original Gist everyone!

@Rican7
Copy link
Author

Rican7 commented Jan 16, 2019

@Rican7
Copy link
Author

Rican7 commented Jun 3, 2019

@Nyura95
Copy link

Nyura95 commented Mar 6, 2020

Nice, thx !
It works very well.

I just change your regex for (\w{2,})([A-Z]).

I have interface with the key ID and your regex transform this in i_d
If someone has a better way :)

@Rican7
Copy link
Author

Rican7 commented Mar 6, 2020

@Nyura95 try checking out this project instead:
https://github.com/Rican7/conjson

It's an expansion on this idea. 😃

@soufi
Copy link

soufi commented Mar 21, 2021

Nice ! Thank you for sharing !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment