Skip to content
This repository was archived by the owner on Sep 4, 2025. It is now read-only.

Conversation

skimata
Copy link

@skimata skimata commented Feb 6, 2017

(this is a cleaner PR)

type Post struct {
	Blog          `jsonapi:"-"`
	ID            uint64     `jsonapi:"primary,posts"`
	BlogID        int        `jsonapi:"attr,blog_id"`
	ClientID      string     `jsonapi:"client-id"`
	Title         string     `jsonapi:"attr,title"`
	Body          string     `jsonapi:"attr,body"`
	Comments      []*Comment `jsonapi:"relation,comments"`
	LatestComment *Comment   `jsonapi:"relation,latest_comment"`
}

@gonzalo-bulnes
Copy link

I can confirm that this PR works as expected. Thanks @skimata!

@Azuka
Copy link

Azuka commented May 26, 2017

Following up: any updates on this? This would be nice to have.

Copy link
Contributor

@aren55555 aren55555 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good; needs a couple fixes and a conflict resolved.

if shouldIgnoreField(tag) {
continue
}
model := reflect.ValueOf(modelValue.Field(i).Addr().Interface())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be model =

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think whether I assign to the original argument, or shadow it here, it shouldn't make a difference since the main loop of this function works off of modelValue.

Between assign/overwriting to the original argument vs initializing a new var, I feel like the latter is preferred. But to avoid confusion, I'll pass it directly to unmarshalNode() vs using a shadowed var.

Also, note, w/ handling annotationRelation, we don't overwrite the original model argument. https://github.com/google/jsonapi/blob/master/request.go#L474

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My gometalinter actually caught this not me :)


// As a final catch-all, ensure types line up to avoid a runtime panic.
if fieldValue.Kind() != v.Kind() {
// Ignore interfaces since interfaces are poly
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What did you mean by "poly"?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

polymorphic. But if you feel that isn't the correct term, a more accurate comment is welcome.

Why does this matter?
Basically, this "final catch-all" was introduced when I rebased, and it adversely affected our use of use interface{} struct fields as a generic JSON object.

We were doing something like this:

type Model struct {
   Raw  interface{}  `jsonapi:"attr,raw"`
}

...	

json.Unmarshal(jsonByteData, model.Raw)

if shouldIgnoreField(tag) {
continue
}
model := modelValue.Field(i).Addr().Interface()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be model =...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see similar comment, I'll pass directly to unmarshalNode()

}

func isEmbeddedStruct(sField reflect.StructField) bool {
if sField.Anonymous && sField.Type.Kind() == reflect.Struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be simplified by returning the comparison; don't need if

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}

func shouldIgnoreField(japiTag string) bool {
if strings.HasPrefix(japiTag, annotationIgnore) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be simplified by returning the comparison; don't need if

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}

// assert encoding from model to jsonapi output
expected := `{"data":{"type":"things","id":"1","attributes":{"bar":"barry","bat":"batty","buzz":99,"fizz":"fizzy","foo":"fooey"}}}`
Copy link
Contributor

@aren55555 aren55555 Jul 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should avoid adding string comparisons. Semantic JSON comparison is preferred... could add a test helper method like:

func isJSONEqual(b1, b2 []byte) (result bool, err error) {
	var i1, i2 interface{}
	if err = json.Unmarshal(b1, &i1); err != nil {
		return
	}
	if err = json.Unmarshal(b2, &i2); err != nil {
		return
	}
	result = true
	return
}

model.Bat = "batty"

buf := bytes.NewBuffer(nil)
if err := MarshalOnePayload(buf, model); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be updated to MarshalPayload (if you want []byte) or Marshal if you want a Payloader

}

type Model struct {
Thing
Copy link
Contributor

@aren55555 aren55555 Jul 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some additional tests should be added to demonstrate what should happen when fields are overlapping. Ie both have a field w/ primary annotation or an attr with the same name has been used.

That behaviour will become expected by users of this lib; and such tests would ensure we don't break that expectation.

@skimata skimata mentioned this pull request Jul 19, 2017
@aren55555
Copy link
Contributor

Refer to: #100

@aren55555 aren55555 closed this Jul 20, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants