-
Notifications
You must be signed in to change notification settings - Fork 156
Consider updating library to use pointers for optional fields #56
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
Comments
@zorkian ping! |
Hey this is a fantastic question and thanks for the ping. I agree that we need to support the functionality, but I also think it's ugly as heck. We use lots of protobufs in Go at my dayjob and those get really messy. It's doable and it's fine and it seems to be the way that most APIs go but it leaves me wondering if there's not a better way. If a field is truly optional then having it be a pointer seems reasonable. That way most of the time the user won't specify it but if they need to they can (with the added and frustrating verbosity). Hmm. Okay so I was messing around in the Playground and am wondering how bad something like this is -- I know the performance is crap but I'm not sure this API is ever used in performance-critical places (may be a pipe dream to wish it wasn't): https://play.golang.org/p/-LJSAHFY6h What do you think about that, does it make you super sad? We can even get fancier and use Thoughts? |
I think making optional fields use pointers is reasonable. Would it be okay if I made a PR to make Yaxis struct's fields into pointers? Right now when I'm trying to use this, I can't distinguish between Yaxis.Min = 0 and Yaxis.Min = unset, meaning graphs that I'm making end up very broken. |
@zorkian I think that something like that code snippet you posted would make optional structs cleaner. I'm not super familiar with Go style, so I don't know how other libraries have handled the same situation. That said, it looks like a good solution. (to be clear, referring to this snippet: https://play.golang.org/p/-LJSAHFY6h) |
We should circle back to this and figure out what we want to do given that there's another request open #75 related to this. |
Given:
I propose:
While I don't like the idea of pointer fields everywhere, it's at least something we're used to and seems to be a reasonable way of moving forward. Thoughts on this? Any changes/suggestions? |
I agree with the approach proposed (cut current(ish) version and start v2 branch), but I'd suggest some additional changes to more completely deal with the API quirks. One example is that certain fields are optional, but also can be either a number or a string (which is a number) depending on which graph type they're included in. It's late here and I don't have my notes around, but it's something like:
I had previously submitted PRs to change from json.Int (or float) to json.Number in some cases, but I imagine this (v2 branch creation) would be an appropriate time to make these breaking changes. |
Hi, I'd like to 👍 for fixing this issue as we hit it as well while working on alphagov/paas-cf#738. We are going to implement some dirty workaround in the meantime by using curl and API directly to update |
I was letting ~enough time to go by for any objections/feedback but haven't heard anything, so let's go ahead with the plan to switch everything to pointers and cut it as v2. I'm at my day-job right now and won't have time to work on this today, so if you're particularly motivated you can start the conversion and we can review it. If not, I should have time sometime within the next week to do the work. |
Cool, I'm busy as well this week but I might be able to do sth this weekend. No promises though :) |
Just got off a 3 hour flight and have a rough cut I should be able to push out before the weekend. |
Since we have discovered that go-datadog library has problems with setting default options for some monitor settings(zorkian/go-datadog-api#56) we need to use this script to ensure all options that we care about have desired values.
Since we have discovered that go-datadog library has problems with setting default options for some monitor settings(zorkian/go-datadog-api#56) we need to use this script to ensure all options that we care about have desired values.
Since we have discovered that go-datadog library has problems with setting default options for some monitor settings(zorkian/go-datadog-api#56) we need to use this script to ensure all options that we care about have desired values.
Since we have discovered that go-datadog library has problems with setting default options for some monitor settings(zorkian/go-datadog-api#56) we need to use this script to ensure all options that we care about have desired values.
Since we have discovered that go-datadog library has problems with setting default options for some monitor settings(zorkian/go-datadog-api#56) we need to use this script to ensure all options that we care about have desired values.
Because of issue[1] with datadog library used by TF datadog provider, we need to run additional scripts after TF run to finish up configuration. These scripts are written in ruby and require dogapi gem. Modify TF container to be based on ruby:alpine and add dogapi gem. [1] zorkian/go-datadog-api#56
… return pointers for common types.
Have raised #83 as proof of concept. See my notes in the PR, happy to discuss either here or there! |
Because of datadog go library issue (zorkian/go-datadog-api#56) we need to apply false require_full_window attributes in additional step after terraform. This can be reverted once datadog library is fixed and DataDog TF provided uses fixed library.
Since we have discovered that go-datadog library has problems with setting default options for some monitor settings(zorkian/go-datadog-api#56) we need to use this script to ensure all options that we care about have desired values.
Because of datadog go library issue (zorkian/go-datadog-api#56) we need to apply false require_full_window attributes in additional step after terraform. This can be reverted once datadog library is fixed and DataDog TF provided uses fixed library.
Since we have discovered that go-datadog library has problems with setting default options for some monitor settings(zorkian/go-datadog-api#56) we need to use this script to ensure all options that we care about have desired values.
Because of datadog go library issue (zorkian/go-datadog-api#56) we need to apply `false` require_full_window attributes in additional step after terraform. This can be reverted once datadog library is fixed and DataDog TF provided uses fixed library.
Since we have discovered that go-datadog library has problems with setting default options for some monitor settings(zorkian/go-datadog-api#56) we need to use this script to ensure all options that we care about have desired values.
Because of datadog go library issue (zorkian/go-datadog-api#56) we need to apply `false` require_full_window attributes in additional step after terraform. This can be reverted once datadog library is fixed and DataDog TF provided uses fixed library.
Since we have discovered that go-datadog library has problems with setting default options for some monitor settings(zorkian/go-datadog-api#56) we need to use this script to ensure all options that we care about have desired values.
Because of datadog go library issue (zorkian/go-datadog-api#56) we need to apply `false` require_full_window attributes in additional step after terraform. This can be reverted once datadog library is fixed and DataDog TF provided uses fixed library.
Since we have discovered that go-datadog library has problems with setting default options for some monitor settings(zorkian/go-datadog-api#56) we need to use this script to ensure all options that we care about have desired values. Also, as ruby library for DataDog api is re-creating a monitor every time it does update we need to send all options that were previously set for the monitor to not fallback to monitor defaults.
Because of datadog go library issue (zorkian/go-datadog-api#56) we need to apply `false` require_full_window attributes in additional step after terraform. This can be reverted once datadog library is fixed and DataDog TF provided uses fixed library.
Since we have discovered that go-datadog library has problems with setting default options for some monitor settings(zorkian/go-datadog-api#56) we need to use this script to ensure all options that we care about have desired values. Also, as ruby library for DataDog api is re-creating a monitor every time it does update we need to send all options that were previously set for the monitor to not fallback to monitor defaults.
Because of datadog go library issue (zorkian/go-datadog-api#56) we need to apply `false` require_full_window attributes in additional step after terraform. This can be reverted once datadog library is fixed and DataDog TF provided uses fixed library.
Since we have discovered that go-datadog library has problems with setting default options for some monitor settings(zorkian/go-datadog-api#56) we need to use this script to ensure all options that we care about have desired values. Also, as ruby library for DataDog api is re-creating a monitor every time it does update we need to send all options that were previously set for the monitor to not fallback to monitor defaults.
Because of datadog go library issue (zorkian/go-datadog-api#56) we need to apply `false` require_full_window attributes in additional step after terraform. This can be reverted once datadog library is fixed and DataDog TF provided uses fixed library.
Since we have discovered that go-datadog library has problems with setting default options for some monitor settings(zorkian/go-datadog-api#56) we need to use this script to ensure all options that we care about have desired values. Also, as ruby library for DataDog api is re-creating a monitor every time it does update we need to send all options that were previously set for the monitor to not fallback to monitor defaults.
Because of datadog go library issue (zorkian/go-datadog-api#56) we need to apply `false` require_full_window attributes in additional step after terraform. This can be reverted once datadog library is fixed and DataDog TF provided uses fixed library.
Copy of the most part of my comment in #83, so people know what's up with this issue: I've coded something up that generates m := datadog.Monitor{}
c := datadog.Creator{}
// Use SetXx:
c.SetName("Joe Creator")
m.SetName("Monitor all the things")
m.SetMessage("Fat electrons in the lines")
// Use HasXx:
if m.HasMessage() {
fmt.Printf("Found message %s\n", m.GetMessage())
}
// Or maybe you prefer a tuple with the value and a boolean if it was ever set
// and use GetXxOk
if v, ok := m.GetMessageOk() ; ok {
fmt.Printf("Found message %s\n", v)
} I still like having the other helpers around, and keep support for doing: // You could still initialize the struct in one swoop
_ = datadog.Monitor{
Name: datadog.String("Monitor other things"),
Creator: &datadog.Creator{
Name: datadog.String("Joe Creator"),
},
} I'll push up some changes to this PR hopefully today, else tomorrow. |
Pushed changes up, see #83 |
…ields WIP GH-56 Refactor to use pointers for all fields.
#83 has been merged 🎉 Do note that this has been merged to v2, which you can use by importing |
* provider/datadog: Pulls v2 and removes v1 of library go-datadog-api. See zorkian/go-datadog-api#56 for context. * Fixes bug in backoff implementation that decreased performance significantly. * Uses pointers for field types, providing support of distinguishing between if a value is set, or the default value for that type is effective. * provider/datadog: Convert provider to use v2 of go-datadog-api. * provider/datadog: Update vendored library. * provider/datadog: Update dashboard resource to reflect API updates.
* provider/datadog: Pulls v2 and removes v1 of library go-datadog-api. See zorkian/go-datadog-api#56 for context. * Fixes bug in backoff implementation that decreased performance significantly. * Uses pointers for field types, providing support of distinguishing between if a value is set, or the default value for that type is effective. * provider/datadog: Convert provider to use v2 of go-datadog-api. * provider/datadog: Update vendored library. * provider/datadog: Update dashboard resource to reflect API updates.
* provider/datadog: Pulls v2 and removes v1 of library go-datadog-api. See zorkian/go-datadog-api#56 for context. * Fixes bug in backoff implementation that decreased performance significantly. * Uses pointers for field types, providing support of distinguishing between if a value is set, or the default value for that type is effective. * provider/datadog: Convert provider to use v2 of go-datadog-api. * provider/datadog: Update vendored library. * provider/datadog: Update dashboard resource to reflect API updates.
Effectively a revert of 8e12c13. The upstream go library issue has now been fixed: zorkian/go-datadog-api#56 This addresses #1170
Effectively a revert of 8e12c13. The upstream go library issue has now been fixed: zorkian/go-datadog-api#56 This addresses #1170
Effectively a revert of 8e12c13. The upstream go library issue has now been fixed: zorkian/go-datadog-api#56 This addresses #1170
Effectively a revert of 8e12c13. The upstream go library issue has now been fixed: zorkian/go-datadog-api#56 This addresses #1170
Effectively a revert of 8e12c13. The upstream go library issue has now been fixed: zorkian/go-datadog-api#56 This addresses #1170
Hi there,
So far using default values has worked for us but it will not work in the case where values can either be set or not, and not setting them can influence behaviour.
An example issue issue I ran into
require_full_window
which is a Boolean, and optional. If the option is not set Datadog uses custom behaviour, which is desirable in some cases.Using the current API this field defaults to false, which is different to it not being set. I suspect, but have not checked if there are other cases where we ran into this issue.
A solution is to refactor the library to use pointers, as this allows us to check if a value is actually set. The upside is more precision, the downside is that clients using the library now have to do a little more work to use pointers.
A struct like
Monitor
currently looks like so:And would look like this using pointers for optional fields only:
Or like so using pointers for all fields:
There are different ways to go about this:
Will Noris wrote an insightful blogpost about this at go-rest-apis-and-pointers, which relates to his adventures in issue 19 at go-github. Go-github did make the switch to use pointers for all the things, and created helper functions to make using it a little less tedious. The result is not very pleasant to read and use, but it is precise.
There is an interesting discussion making a similar choice in issue 2330 of swagger-api.
I'm leaning toward using pointers for optional fields. @zorkian thoughts?
Cheers,
Otto
The text was updated successfully, but these errors were encountered: