3

I have written an API with Golang. This API does receive data from other services then it responses to users in type of JSON string. Here is the problems I got.

type message struct {
    Data string `json:"data"`
}

func test(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    data := // Retrieve message that contain backslash
    json.NewEncoder(w).Encode(message{Data: data})
}

` If there is a backslash in data that receive from other API. This API will send the response with double backslashes.

Example.

Received data: "asdasdasd\asdasdasd"

Response data: {"data": "asdasdasd\\asdasdasd"}

I have try to figure this out. Here what I got. All of this will be fine if I try to print out in the screen by using fmt.Println().

I only get problem when I try to send those out put in JSON string. Therefore, is there any way to send those data without double backslashes?

3
  • 3
    Backslash is a special character, it must be escaped, i.e. converted from \ to \\. So the encoder is correct. Why do you want to disable the conversion? Commented Aug 28, 2017 at 9:03
  • 1
    If your data is already a valid JSON, then define the Data in message struct as json.RawMessage. Then in the encoder, define the message as message{Data: json.RawMessage(data)} Commented Aug 28, 2017 at 9:21
  • 1
    {"data": "asdasdasd\\asdasdasd"} is the correct JSON representation of the string asdasdasd\asdasdasd Commented Aug 29, 2017 at 7:30

4 Answers 4

2

As suggested in the comments, json.RawMessage does the trick.

data := map[string]interface{}{}
data["date"] = json.RawMessage([]byte(`"\/Date(1590105600000)\/"`))

b := new(bytes.Buffer)
json.NewEncoder(b).Encode(data)

fmt.Println(b.String())
// {"date":"\/Date(1590105600000)\/"}
Sign up to request clarification or add additional context in comments.

Comments

1

I asked pretty much the same question a couple days ago, here's the post.

Basically you don't want your Data to be a string but an interface{} instead.

type message struct {
    Data interface{} `json:"data"`
}

I think this may apply to you also. And if you want to go RESTFul and return different types of structs, this is definitely the way to go.

Comments

0

Golang default render will escape JSON, but if you want to disable it you need to define custom renderer like this:

encoder := json.NewEncoder(w)
encoder.SetEscapeHTML(false)
encoder.Encode(data)

Comments

-1

You can create a custom method and replace double backslashes with a single one.
Something like that:

func JSONMarshal(v interface{}, backslashEscape bool) ([]byte, error) {
    b, err := json.Marshal(v)

    if backslashEscape {
        b = bytes.Replace(b, []byte(`\\`), []byte(`\`), -1)
    }
    return b, err
}

The json/encoder packages has also DisableHTMLEscaping, if set to true, default is false, it allows you to escape HTML chars.

3 Comments

Thank you for your solution. It works!! But there is some issue you need to fix in this code. You have to use backtick (`) instead of double-qoute (")
It seem that your fixed version using single-quote, not backtick or grave accent.
Edit my answer by clicking edit link. I'm from smartphone and I'll accept your edit

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.