Support unrecognized properties for EV features#1500
Conversation
|
|
| * @param unrecognizedProperties parameters to add to request | ||
| */ | ||
| @NonNull | ||
| public Builder unrecognizedProperties( |
There was a problem hiding this comment.
Why not make the abstract unrecognized method public in DirectionsJsonObject.Builder? We definitely see a use-case for this method being public. Or add unrecognizedProperties as public function to the abstract builder if we don't want to expose the SerializableJsonElement.
cc @VysotskiVadim
There was a problem hiding this comment.
- It wasn't public so I thought there was a reason for it. So we should only make it public when needed, a white list, not black list;
- The
unrecognized()method acceptsMap<String, SerializableJsonElement>which is not very convenient for the end user, so yes, I'd prefer addingunrecognizedPropertieswithMap<String, JsonElement>instead.
So is there a reason why it's not public?
| /** | ||
| * Provides utility methods to work with unrecognized properties. | ||
| */ | ||
| public final class UnrecognizedPropertiesUtils { |
There was a problem hiding this comment.
Should this be public? DirectionsJsonObject already exposes these accessors.
There was a problem hiding this comment.
I want to access it from the service-directions-refresh-models module. To avoid code duplicating.
There was a problem hiding this comment.
I imagine we don't need this if we expose the map getters.
|
|
||
| abstract static class Builder<T extends Builder> { | ||
| @NonNull | ||
| abstract T unrecognized(@Nullable Map<String, SerializableJsonElement> value); |
There was a problem hiding this comment.
Same as above, why not making this public?
|
|
||
| @Nullable | ||
| @UnrecognizedJsonProperties | ||
| abstract Map<String, SerializableJsonElement> unrecognized(); |
There was a problem hiding this comment.
We could consider making this public, refs NAVAND-778. Doesn't have to happen in this PR though.
There was a problem hiding this comment.
How will making this public help NAVAND-778? For the case described there it's more like adding a method addUnrecognizedProperties instead of the current one that resets them.
There was a problem hiding this comment.
A public getter would allow us to first get the properties map, mutate them, and set them back. As we would do with any other builder object parameter. The getter and setter methods in this case need to work on the same map type so that developers don't need to do any parsing themselves, that's why I was hoping to expose a single function in the abstract class instead of adding explicit getter and setters manually everywhere.
There was a problem hiding this comment.
OK, makes sense but it's not very convenient to use with SerializableJsonElement. But I guess we could add convenience methods directly to DirectionsJsonObject and DirectionsRefreshJsonObject. WDYT?
There was a problem hiding this comment.
Sure, as we're discussing in #1500 (comment) JsonElement might be better.
| */ | ||
| @NonNull | ||
| public Builder unrecognizedProperties( | ||
| @Nullable Map<String, JsonElement> unrecognizedProperties |
There was a problem hiding this comment.
RouteOptions.Builder exposes this map as Map<String, String>, we should align this one way or the other. For the general purpose JsonElement does look like a better candidate, but again only if we don't want to expose the SerializableJsonElement. @VysotskiVadim I remember you had some thoughts about it in the past.
There was a problem hiding this comment.
Yes, here we definitely need JsonElement. The structure will be complex.
For RouteOptions it's only about get parameters, that's why strings are used.
These are different use cases so I'm not sure if we should complicate RouteOptions usage with converting it all to JsonElement. But we could have 2 methods for RouteOptions to keep both consistency and usability.
There was a problem hiding this comment.
@VysotskiVadim I remember you had some thoughts about it in the past.
the initial idea was to expose as little as possible to simplify future changes.
For RouteOptions it's only about get parameters, that's why strings are used.
that's right.
These are different use cases so I'm not sure if we should complicate RouteOptions usage with converting it all to JsonElement.
I agree with @dzinad. I don't see value in aligning unrecognised properties API between request and response models.
There was a problem hiding this comment.
I don't fully agree. Whether we look at request or response object, they are all DirectionsJsonObjects (or refresh) and support the unrecognized fields in exactly the same way, and that's why I think they should also expose the same API to mutate or reset the properties.
We started with RouteOptions needing some form of unrecognized properties setter, now we need to add the same to LegAnnotation and this could be true at any point in time for any DirectionsJsonObject, depending on what's experimental in the Directions API at a certain time.
Couldn't we expose Map<String, JsonElement> getter and setters for all DirectionsJsonObjects?
There was a problem hiding this comment.
We can if we leave the convenience method for RouteOptions.
There was a problem hiding this comment.
Why couldn't we use only Map<String, JsonElement> for RouteOptions as well?
The only change developers would have to make is wrap their string values in JsonPrimitive(value). That's actually even more flexible because other than string parameters are also acceptable by the Directions API. Of course we can leave the existing function in place but I'd rather deprecate it.
There was a problem hiding this comment.
- It's a breaking change and that's something that would definitely affect the users;
- In the majority of the cases users only need
Map<String, String>. Making them useMap<String, JsonElement>will force them to write more boiler-plate code on their side.
I'm strongly in favour of leaving the convenience method as-is. We'll provide a more flexible options: if they want something other than strings, they can use the new method. And I'm not suggesting to add Map<String, String> everywhere: only leave it where it already is and where it makes sense to have it.
There was a problem hiding this comment.
It's a breaking change and that's something that would definitely affect the users;
We'd not be removing the old function, only deprecating it.
In the majority of the cases users only need Map<String, String>. Making them use Map<String, JsonElement> will force them to write more boiler-plate code on their side.
Map<String, String> is limiting and actually somewhat incorrect. For example, look at ev_max_charge parameter in https://docs.mapbox.com/api/navigation/directions/#parameters-for-electric-vehicle-routing - it's an integer but we'd recommend (and today require) developers pass it as a string. JsonPrimitive(integer) would be more accurate here.
In any case, we can discuss and consider the deprecation separately, the old function has to stay in place regardless.
| * Provides a base class for Directions model classes. | ||
| */ | ||
| public class DirectionsRefreshJsonObject implements Serializable { | ||
| public abstract class DirectionsRefreshJsonObject implements Serializable { |
There was a problem hiding this comment.
it's a breaking change, isn't it? Users who create the object won't be able to this, right? TBH I don't remember which visibility default constructor from java has 🙂
There was a problem hiding this comment.
even if it's a breaking change we can consider the previous implementation as a bug. I believe we already did it once 🙂
There was a problem hiding this comment.
TBH I don't remember which visibility default constructor from java has
It's public with no arguments.
it's a breaking change, isn't it?
You are right. Good catch! I see the following options here:
- Commit the breaking change and reduce the constructor visibility for the future. Why would anyone create an empty
DirectionsRefreshJsonObject?.. But that would still break semver; - Up the major version. I'm not sure about the policy on that. @LukasPaczos could you chime in here?
- Add unrecognized properties directly to
DirectionsRouteRefresh. That's the only place they are needed right now. But it's not very flexible; - Add compile-time support for EV features. Not really consistent with the feature being in beta;
There was a problem hiding this comment.
Actually I had the same problem adding unrecognized properties: https://github.com/mapbox/mapbox-java/pull/1394/files#r848311760 😄
There was a problem hiding this comment.
Haha, nice
Then maybe we should think about reducing the visibility of everything that should not be used directly? These are mostly constructors but it makes sense to double-check. That's a separate issue though.
There was a problem hiding this comment.
Let's make the change as last time around 👍
Then maybe we should think about reducing the visibility of everything that should not be used directly?
Good ticket to have for the next major version 👍
a3e8487 to
7be690f
Compare
No description provided.