manyminds / api2go

JSONAPI.org Implementation for Go
MIT License
700 stars 94 forks source link

Annotations need their own namespace #309

Open drauschenbach opened 6 years ago

drauschenbach commented 6 years ago

I store my [DTO's|https://en.wikipedia.org/wiki/Data_transfer_object] in etcd, and then serialize them via JSONAPI.

I've noticed that I'm accumulating duplicate DTO's - one for etcd storage, and one for api2go -- because they have different JSON serialization requirements.

  1. etcd requires me to serialize foreign keys
  2. api2go requires me to suppress serialization of foreign keys, and publish them via model functions.

This could be solved by using api2go's own model field annotations, instead of piggybacking on JSON serialization annotations.

sharpner commented 6 years ago

In order to reduce the duplication you could also make use of embedding:

Playlink

package main

import (
    "encoding/json"
    "fmt"
)

type Api2go struct {
    SharedField string 
    ForeignKey string `json:"-"`
}

type Etcd struct {
    Api2go
    ForeignKey string `json:"ForeignKey"`
}

func main() {
    etcd := Etcd{ForeignKey: "ETCD Key"}
    etcd.SharedField = "We both use it"

    api2go := Api2go{ForeignKey: "Api2go Key"}
    api2go.SharedField =  "We both use it"
    api2gojson, _ := json.Marshal(api2go)
    etcdjson, _ := json.Marshal(etcd)
    fmt.Println(fmt.Sprintf("api2go %s vs etcd %s", api2gojson, etcdjson))
}

but since api2go heavily relies on the json package internally, we cannot simply rename the json tags.

I hope it helps :)

drauschenbach commented 6 years ago

If I'm not mistaken, that use of embedding causes the both the Etcd struct and the nested Api2go struct to both have a ForeignKey field, which gives rise to ambiguity, and duplication in initialization. Probably not worth it...

sharpner commented 6 years ago

Hmm, it might be that I misunderstood your question.

Can you provide some code so we can talk about a specific implementation?

Would make it easier :)

drauschenbach commented 6 years ago

@sharpner So in your example would you populate etcd.ForeignKey= or etcd.Api2go.ForeignKey=? They're two separate fields now right? Which leads to the ambiguity I was referring to.

sharpner commented 6 years ago

Well it's true that this approach contains a duplicate field, but then again the field should behave differently in two different use cases.

Since for us, it's not feasible. to switch back from json struct tags to some custom one likejsonapi, we have to find another way of how we can implement your use case ;)