Skip to content
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

Support custom JSON unmarshaling and json.Unmarshaler interface in decoding #42

Closed
Perlence opened this issue Aug 9, 2015 · 11 comments
Closed

Comments

@Perlence
Copy link

Perlence commented Aug 9, 2015

Can I have a http.Response as result of GET request? I want to do custom JSON unmarshalling.

@huandu
Copy link
Owner

huandu commented Aug 10, 2015

Can you please let me know your scenario? Why do you need to do custom JSON unmarshalling?

@Perlence
Copy link
Author

I'm requesting user's feed GET me/feed and I need to decode objects in data into structs, that have field CreatedTime of type pq.NullTime. The way decoder works, it asserts that value at created_time must be an object.

I couldn't think of any better solution other than break my struct in two: one that has not null fields, and second that embeds first struct plus field CreatedTime of pq.NullTime. Then I decode post into first struct and embed it, then decode field created_time in second struct.

All this feels very clunky, I think it would be pretty convenient to implement json.Unmarshaler interface for my NullTime.

@huandu
Copy link
Owner

huandu commented Aug 10, 2015

I see. If this package provides an interface facebook.Unmarshaler just like what json package implements, is it OK for you?

@Perlence
Copy link
Author

I guess that would resolve the problem.

@huandu
Copy link
Owner

huandu commented Aug 11, 2015

Fine. I'll implement it soon.

huandu added a commit that referenced this issue Aug 11, 2015
@huandu
Copy link
Owner

huandu commented Aug 11, 2015

@Perlence I implemented it in latest master code. Please take a look and have a try.

@huandu huandu changed the title Raw http.Response Support custom JSON unmarshaling and json.Unmarshaler interface in decoding Aug 11, 2015
@Perlence
Copy link
Author

Thank you!

When I implemented json.Unmarshaler interface for the whole struct it worked:

type FeedResult struct {
    Data   []FacebookPost `json:"data"`
    Paging Paging         `json:"paging"`
}

type FacebookPost struct {
    ID          string      `json:"id" db:"id"`
    EntryID     int64       `json:"entry_id" db:"entry_id"`
    Message     string      `json:"message" db:"message"`
    Story       string      `json:"story" db:"story"`
    CreatedTime pq.NullTime `json:"created_time" db:"created_time"`
}

func (p *FacebookPost) UnmarshalJSON(data []byte) error {
    var aux struct {
        ID          string   `json:"id" db:"id"`
        Message     string   `json:"message" db:"message"`
        Story       string   `json:"story" db:"story"`
        CreatedTime NullTime `json:"created_time" db:"created_time"`
    }
    ...
}

type NullTime struct{ pq.NullTime }

func (nt *NullTime) UnmarshalJSON(data []byte) error {
    t, err := time.Parse(dateFmt, string(data))
    if err != nil {
        return errors.Trace(err)
    }

    nt.Time = t
    nt.Valid = !t.IsZero()
    return nil
}

Yeah, I know there's facebook.PagingResult, but I must be able to set paging params myself, e.g. from DB. Anyways, I'm more than happy with such approach, it works fine.
But if I implement json.Unmarshaler only for a field, it does not:

type FeedResult struct {
    Data   []FacebookPost `json:"data"`
    Paging Paging         `json:"paging"`
}

type FacebookPost struct {
    ID          string   `json:"id" db:"id"`
    EntryID     int64    `json:"entry_id" db:"entry_id"`
    Message     string   `json:"message" db:"message"`
    Story       string   `json:"story" db:"story"`
    CreatedTime NullTime `json:"created_time" db:"created_time"`
}

type NullTime struct{ pq.NullTime }

func (nt *NullTime) UnmarshalJSON(data []byte) error {
    ...
}

I get error "field 'data.0.created_time' is not a json object in result." I guess, that's expected.

@huandu
Copy link
Owner

huandu commented Aug 12, 2015

It's a bug in my latest commit. I'll fix it soon.

huandu added a commit that referenced this issue Aug 12, 2015
@huandu
Copy link
Owner

huandu commented Aug 12, 2015

@Perlence Please take a look at latest master code again. Thanks.

@Perlence
Copy link
Author

Yep, it works, thanks 😄

@huandu
Copy link
Owner

huandu commented Aug 17, 2015

Glad to hear it. 😄

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

No branches or pull requests

2 participants