1

In my json data structure I have a string that can have a prefix. When unmarshalling JSON, is it possible to have a function to remove that prefix? I am looking into custom JSON unmarshalling in golang and trying to leverage that.

For example. The payload can be either of the following

{
  "id": "urn:uuid:1234567890"
}

{
  "id": "1234567890"
}

When I do JSON.unmarshall(data, &struct) I'd like the unmarshall function to handle removing the urn:uuid prefix from the string if it is there so the struct will always have the value 1234567890 for id.

6
  • 2
    You can do that by making the id field of the struct have a custom type and have that type implement the json.Unmarshaler interface. Just make sure the id field is actually exported or else it won't get decoded. Commented Sep 6, 2017 at 18:24
  • 1
    Postprocess. basically undoable during unmarshaling if you do not provid your own unmarshaler (too much). Commented Sep 6, 2017 at 18:24
  • If you're looking into customizing unmarshalling, you must already know it's possible, so... what exactly is your question? Commented Sep 6, 2017 at 18:46
  • I'm having some problems actually implementing the custom unmarshalling. I was trying to do it on the whole struct itself. But it as @mkopriva mentioned, its supposed to be done on the id field itself. Commented Sep 6, 2017 at 18:53
  • @Sakib something like this play.golang.org/p/J6iadpsTgO Commented Sep 6, 2017 at 19:17

1 Answer 1

4

You can provide a custom UnmarshalJSON method on the data you need to trim, here is an example implementation, you may need to extend if you have to regex match the start rather than match hard string (or byte array in this case):

go playground

package main

import (
    "bytes"
    "encoding/json"
    "log"
)

var (
    sampleJSON   = []byte(`{"id": "urn:uuid:1234567890"}`)
    prefixToTrim = []byte(`urn:uuid:`)
)

type IDField string

type Data struct {
    ID IDField `json:"id"`
}

func main() {
    d := &Data{}
    err := json.Unmarshal(sampleJSON, d)
    if err != nil {
        log.Fatal(err)
    }

    log.Println(d.ID)
}

// UnmarshalJSON provides custom unmarshalling to trim `urn:uuid:` prefix from IDField
func (id *IDField) UnmarshalJSON(rawIDBytes []byte) error {

    // trim quotes and prefix
    trimmedID := bytes.TrimPrefix(bytes.Trim(rawIDBytes, `"`), prefixToTrim)

    // convert back to id field & assign
    *id = IDField(trimmedID)
    return nil
}
Sign up to request clarification or add additional context in comments.

1 Comment

This is a really sleek solution. My problem is that now when I'm using ID as string, I need to do conversion string(ID). Is there a way around it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.