Skip to content

Less-Tag or Default Tag #73662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
go-shafaq opened this issue May 10, 2025 · 5 comments
Closed

Less-Tag or Default Tag #73662

go-shafaq opened this issue May 10, 2025 · 5 comments

Comments

@go-shafaq
Copy link

Intro

Imagne you dont to have write json:"name" tag every time, Insted you can just define following:

// tag    case
   json  snake_case

And everything works as you want.
Example: with this struct:

type User struct {
    ID        int
    Name      string
    BirthDate string
}

you can get such json:

{
    "id": 314,
    "name": "Jhon",
    "birth_date": "2001-03-14"
}

Isn't It awesome?

This is generally how I see it, If you're short on time, everything important is summarized here.

In the next sections, I’ll go into more detail and share my ideas — but the main point doesn't change.

Strugles

My first strugles with Go

I came to Golang from Java, I did simple pet-project in my internship. At that time I didn't even know I need to write tags. My TeamLead checked apis and said write tags, and I wrote tags with lowerCamelCase. TeamLead checked again and said they use snake_case and I had to rewrite it. At that time I didn't feel good and I felt like I'm doing something that coulde be probrammed.
From that I had ideas

General strugles

Some times we forget about writing tags
Some times we misspell it
Some times It is just lame for us

Attempted to solve

Attempted to solve it on my own.
I found this repo github.com/iancoleman/strcase, It helped me to make my solution.
I did my solution in this repo
github.com/go-shafaq/defcase
It worked but It had same problems
Main problem was/is:

It defundes deafult_case in run time.
Till runtime comes to that line some structures might be complied&cache-in-json-lib and wil not be changed (mostly because of init functions)
Then I had same ideas to make it something like sql.Register, but even This wouldn't solve the problem fully

At the End I thought It should be done in languge level, Otherwise there could be some problems

My Ideas About Impl

Example in code

encoding/josn/encode.go line 1134

				tag := sf.Tag.Get("json")
				if tag == "-" {
					continue
				}
				name, opts := parseTag(tag)
				if !isValidTag(name) {
					name = ""
				} 
				if name == "" && sf.Tag.HasDefaultCase("json") {
				    name = sf.Tag.NameWithDefaultCase("json")
				}

HasDefaultCase(tag) - checks whether a DefaultCase is defined for this tag
NameWithDefaultCase(tag) - returns name formatted in DefaultCase

also option 2in1 NameWithDefaultCase(tag) (string, bool)

How to define

I thougt defining it with in defaultcase.txt, comments in structs.go and go.mod
I mostly like it with-in go.mod

module myapp

...

defaultcase (
    // tag   case        path
      json  snake_case   myapp/internal/models
      bson  camelCase    myapp/internal/models
)

...

These are my ideas on how to implement it. It may not be perfect. And I'm not saying This is the only way to do it.

More Realistic Usage

type User struct {
     ID           string `bson:"_id"`
     Name         string
     BirthDate    string
     Email        string
     Password     string `bson:"-"`
     PasswordHash string `json:"-"`
}

I love Golang

I just want to improve it a little bit

@seankhliao
Copy link
Member

see #63397 (comment)

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale May 10, 2025
@go-shafaq
Copy link
Author

@seankhliao you are misunderstanding me

My idea is not just about JSON, but yeah It will cover it

#63397 is just/mostly about "encoding/json"
"encoding/json/v2" might do something similar with Unmarshal() but not Marshal()

My idea is about writing less tags

Here look:

// Currently
type User struct {
	ID          int    `json:"id" bson:"_id"`
	FirstName   string `json:"first_name" bson:"first_name"`
	LastName    string `json:"last_name" bson:"last_name"`
	Username    string `json:"username" bson:"username"`
	Email       string `json:"email" bson:"email"`
	PhoneNumber string `json:"phone_number" bson:"phone_number"`
}

// My Intention
type User struct {
	ID          int    `bson:"_id"`
	FirstName   string
	LastName    string
	Username    string
	Email       string
	PhoneNumber string
}

It will help to write less code, and you dont have to write one name multiple times (with some casing)

It is not just about "json" tag, this could be used with other tag as well: bson, sql, env, yml, form, ...

@go-shafaq
Copy link
Author

May be I should post in Discussions, can you help with this @seankhliao

@go-shafaq
Copy link
Author

@seankhliao

@seankhliao
Copy link
Member

Other marshalers like bson are free to do their own thing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants