You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jclouds.apache.org by Andrew Phillips <ap...@qrmedia.com> on 2014/09/03 03:52:46 UTC

Using *Options for domain objects?

Reviewing a couple of PRs [1, 2], I noticed a pattern for creating  
subclasses for domain objects that need different attributes depending  
on whether they should be created or updated.

An example looks like

SecurityGroup.createOptions().name("jclouds-test").description("jclouds test  
security group").build())

which seems like nice syntax to me. It's implemented by having a  
"CreateOptions extends SecurityGroup" domain object subclass, whose  
Builder is returned by createOptions().

I added some comments to the PR because the main usage of classes  
named *Options that I'm aware of in jclouds is as a parameter object  
to modify an API call, not as a *domain* object variant.

I'm a bit late to the party here, so apologies if I've missed a  
discussion on this topic. I was wondering if this new naming risks  
confusing users, and was curious to see if anyone has any suggestions...

Regards

ap

[1] https://github.com/jclouds/jclouds-labs-openstack/pull/135
[2] https://github.com/jclouds/jclouds-labs-openstack/pull/132

RE: Using *Options for domain objects?

Posted by Zack Shoylev <za...@RACKSPACE.COM>.
I have updated the PR https://github.com/jclouds/jclouds-labs-openstack/pull/139

Thanks for the help!

________________________________________
From: Andrew Phillips [aphillips@qrmedia.com]
Sent: Monday, September 08, 2014 8:54 AM
To: dev@jclouds.apache.org
Subject: RE: Using *Options for domain objects?

> I was mostly thinking about what method and class names users see
> when they use jclouds apis - we have Options a lot, we have Builders
>  as well.

Well, I think since we're talking here about builders that create
domain objects , rather than builders which create options in the
current jclouds sense of modifying a call, I would say:

createBuilder() // convenience method
-> CreateBuilder // Builder class
-> CreateObject // domain object

and similarly for update.

Admittedly, this doesn't take into account Everett's point about these
really being method options that happen to inherit from domain objects
for convenience (I hope I'm paraphrasing that correctly). If we prefer
that slant, I would go for something like:

createBuilder() // convenience method
-> CreateBuilder // Builder class
-> CreateParams or CreateSpec // method args

But *Params also isn't ideal because we already have *Params objects
in jclouds, and they're something slightly different. We *also* have a
*Spec class [2], which seems to come a little closer to the intention
here.

ap

[1]
https://github.com/jclouds/jclouds/blob/master/core/src/main/java/org/jclouds/rest/annotations/FormParams.java
[2]
https://github.com/jclouds/jclouds/blob/master/providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerSpec.java

RE: Using *Options for domain objects?

Posted by Andrew Phillips <ap...@qrmedia.com>.
> I was mostly thinking about what method and class names users see   
> when they use jclouds apis - we have Options a lot, we have Builders  
>  as well.

Well, I think since we're talking here about builders that create  
domain objects , rather than builders which create options in the  
current jclouds sense of modifying a call, I would say:

createBuilder() // convenience method
-> CreateBuilder // Builder class
-> CreateObject // domain object

and similarly for update.

Admittedly, this doesn't take into account Everett's point about these  
really being method options that happen to inherit from domain objects  
for convenience (I hope I'm paraphrasing that correctly). If we prefer  
that slant, I would go for something like:

createBuilder() // convenience method
-> CreateBuilder // Builder class
-> CreateParams or CreateSpec // method args

But *Params also isn't ideal because we already have *Params objects  
in jclouds, and they're something slightly different. We *also* have a  
*Spec class [2], which seems to come a little closer to the intention  
here.

ap

[1]  
https://github.com/jclouds/jclouds/blob/master/core/src/main/java/org/jclouds/rest/annotations/FormParams.java
[2]  
https://github.com/jclouds/jclouds/blob/master/providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerSpec.java

RE: Using *Options for domain objects?

Posted by Zack Shoylev <za...@RACKSPACE.COM>.
> this is the first instance of this "typesafe domain object options" pattern in jclouds

I was mostly thinking about what method and class names users see when they use jclouds apis - we have Options a lot, we have Builders as well.

________________________________________
From: Ignasi Barrera [nacx@apache.org]
Sent: Monday, September 08, 2014 2:46 AM
To: dev@jclouds.apache.org
Subject: Re: Using *Options for domain objects?

My preference is also "createBuilder".


I.

On 7 September 2014 23:37, Andrew Phillips <ap...@qrmedia.com> wrote:
>> 1) Change to createBuilder / createObject
>> 2) Leave as is (createOptions)
>>
>> Any examples of existing code that can help steer us one way or the other?
>
>
> I hope someone will correct me, but as far as I'm aware this is the first
> instance of this "typesafe domain object options" pattern in jclouds, so I
> unfortunately can't think of any :-(
>
> For what it's worth, my vote is for createBuilder/CreateObject ;-)
>
> ap

Re: Using *Options for domain objects?

Posted by Ignasi Barrera <na...@apache.org>.
My preference is also "createBuilder".


I.

On 7 September 2014 23:37, Andrew Phillips <ap...@qrmedia.com> wrote:
>> 1) Change to createBuilder / createObject
>> 2) Leave as is (createOptions)
>>
>> Any examples of existing code that can help steer us one way or the other?
>
>
> I hope someone will correct me, but as far as I'm aware this is the first
> instance of this "typesafe domain object options" pattern in jclouds, so I
> unfortunately can't think of any :-(
>
> For what it's worth, my vote is for createBuilder/CreateObject ;-)
>
> ap

RE: Using *Options for domain objects?

Posted by Andrew Phillips <ap...@qrmedia.com>.
> 1) Change to createBuilder / createObject
> 2) Leave as is (createOptions)
>
> Any examples of existing code that can help steer us one way or the other?

I hope someone will correct me, but as far as I'm aware this is the  
first instance of this "typesafe domain object options" pattern in  
jclouds, so I unfortunately can't think of any :-(

For what it's worth, my vote is for createBuilder/CreateObject ;-)

ap

RE: Using *Options for domain objects?

Posted by Zack Shoylev <za...@RACKSPACE.COM>.
Let's keep this alive, as I would like to finish my cleanup PR (this should only affect Neutron, so far).

I think the top 2 suggestions are (did I miss anything?):

1) Change to createBuilder / createObject
2) Leave as is (createOptions)

Any examples of existing code that can help steer us one way or the other?

RE: Using *Options for domain objects?

Posted by Andrew Phillips <ap...@qrmedia.com>.
> createBuilder gives you the CreateBuilder which gives you a CreateObject.
> (replace with update for the other one).

+1 for CreateObject/UpdateObject as the names of the domain classes  
and CreateBuilder/UpdateBuilder for the builder names.

I personally also think that Domain.createWith(...) reads nicely, but  
for consistency with the many instances of Domain.builder() I would  
probably vote for Domain.createBuilder(...) and  
Domain.updateBuilder(...) here.

ap

RE: Using *Options for domain objects?

Posted by Zack Shoylev <za...@RACKSPACE.COM>.
Another suggestion:
createBuilder gives you the CreateBuilder which gives you a CreateObject.
(replace with update for the other one).

________________________________________
From: Jeremy Daggett [jeremy.daggett@RACKSPACE.COM]
Sent: Thursday, September 04, 2014 4:59 PM
To: dev@jclouds.apache.org
Subject: Re: Using *Options for domain objects?

Definitely -1 to ³request²Š ;)

I have been spending quite a bit of time on option related classes over
the past couple of weeks. From what I have observed, most option classes
extend HttpRequestOptions, which is only concerned with headers, queries,
and form params.

Logically, when I hear the term ³options², to me it means ³here are the
options I need to create/update this resource². Then, its not just about
headers, queries and form parameters anymore.

Either ³CreateTemplate² or ³CreateParams² could work. After getting into
OpenStack Heat templates a little more, I might have a differing opinion!
heh

FWIW, if we change the createOptions()/updateOptions() builders to
createWith()/updateWith() instead, it might make a little more sense:

  Port port = portApi.create(Port.createWith(network.getId()).build());

versus:

  Port port = portApi.create(Port.createOptions(network.getId()).build());

It flows a little more nicely IMHO!



/jd


On 9/4/14, 12:58 PM, "Andrew Phillips" <ap...@qrmedia.com> wrote:

>> The new pattern still encapsulates options for creating a resource
>> though. The name seems appropriate. To me, createOptions() says
>> "build me the options for creating a resource".
>
>That seems logical, but I'm just thinking in terms of how *Options is
>used everywhere else in jclouds: it's an *additional* argument to a
>call which modifies the way the response is provided. And it's almost
>always accompanied by a version of the call that does not require
>options.
>
>Agreed that *Request probably isn't a good alternative as, if
>anything, it's even more overloaded. CreateParams? CreateArgs?
>CreateTemplate?
>
>ap


Re: Using *Options for domain objects?

Posted by Jeremy Daggett <je...@RACKSPACE.COM>.
Definitely -1 to ³request²Š ;)

I have been spending quite a bit of time on option related classes over
the past couple of weeks. From what I have observed, most option classes
extend HttpRequestOptions, which is only concerned with headers, queries,
and form params. 

Logically, when I hear the term ³options², to me it means ³here are the
options I need to create/update this resource². Then, its not just about
headers, queries and form parameters anymore.
 
Either ³CreateTemplate² or ³CreateParams² could work. After getting into
OpenStack Heat templates a little more, I might have a differing opinion!
heh

FWIW, if we change the createOptions()/updateOptions() builders to
createWith()/updateWith() instead, it might make a little more sense:

  Port port = portApi.create(Port.createWith(network.getId()).build());

versus:

  Port port = portApi.create(Port.createOptions(network.getId()).build());

It flows a little more nicely IMHO!



/jd


On 9/4/14, 12:58 PM, "Andrew Phillips" <ap...@qrmedia.com> wrote:

>> The new pattern still encapsulates options for creating a resource
>> though. The name seems appropriate. To me, createOptions() says
>> "build me the options for creating a resource".
>
>That seems logical, but I'm just thinking in terms of how *Options is
>used everywhere else in jclouds: it's an *additional* argument to a
>call which modifies the way the response is provided. And it's almost
>always accompanied by a version of the call that does not require
>options.
>
>Agreed that *Request probably isn't a good alternative as, if
>anything, it's even more overloaded. CreateParams? CreateArgs?
>CreateTemplate?
>
>ap


Re: Using *Options for domain objects?

Posted by Andrew Phillips <ap...@qrmedia.com>.
> The new pattern still encapsulates options for creating a resource   
> though. The name seems appropriate. To me, createOptions() says   
> "build me the options for creating a resource".

That seems logical, but I'm just thinking in terms of how *Options is  
used everywhere else in jclouds: it's an *additional* argument to a  
call which modifies the way the response is provided. And it's almost  
always accompanied by a version of the call that does not require  
options.

Agreed that *Request probably isn't a good alternative as, if  
anything, it's even more overloaded. CreateParams? CreateArgs?  
CreateTemplate?

ap

Re: Using *Options for domain objects?

Posted by Everett Toews <ev...@RACKSPACE.COM>.
On Sep 3, 2014, at 3:36 AM, Ignasi Barrera <na...@apache.org> wrote:

> I also like the syntax and think that's a pattern we could use in more
> places.
> 
> Regarding the naming I'm +1 to change the *Options to *Request or something
> else to avoid confusion with the already xisting Options pattern.

The new pattern still encapsulates options for creating a resource though. The name seems appropriate. To me, createOptions() says "build me the options for creating a resource".

Request is a bit generic and overloaded. In the web service world, all calls are a request. It doesn’t distinguish if parts of that request are optional or required.

Everett

RE: Using *Options for domain objects?

Posted by Andrew Phillips <ap...@qrmedia.com>.
> I am happy to see (so far) nobody has issues with the pattern as it   
> exists currently - except for naming.
> *Request sounds good to me, but the reason currently we use *Options  
>  is that it is similar (and thus supposedly easier for users) to   
> existing user code. It might be more confusing for jclouds   
> developers though...

Since users are also exposed to the "other" jclouds "*Options"  
classes, I would suspect that any potential confusion here could  
affect jclouds users, too. No hard data on that, though.

A suggestion: how about naming the classes *Request, as Ignasi  
suggested, and the helper methods either

SecurityGroup.create()... or

SecurityGroup.forCreate()

or so?

ap

RE: Using *Options for domain objects?

Posted by Zack Shoylev <za...@RACKSPACE.COM>.
I am happy to see (so far) nobody has issues with the pattern as it exists currently - except for naming.
*Request sounds good to me, but the reason currently we use *Options is that it is similar (and thus supposedly easier for users) to existing user code. It might be more confusing for jclouds developers though...

In order to keep this thread going (and also if you want some more reading on this), I just added a blog post to the website. Most of it is related. It mostly targets new contributors, though.
http://jclouds.apache.org/blog/2014/09/03/better-builders/
________________________________________
From: Andrew Gaul [gaul@apache.org]
Sent: Wednesday, September 03, 2014 9:49 AM
To: dev@jclouds.apache.org
Subject: Re: Using *Options for domain objects?

I also prefer the builder pattern for options.  A lot of older code have
mutable options, with the NONE constant actually allowing mutations!

On Wed, Sep 03, 2014 at 09:36:19AM +0100, Ignasi Barrera wrote:
> I also like the syntax and think that's a pattern we could use in more
> places.
>
> Regarding the naming I'm +1 to change the *Options to *Request or something
> else to avoid confusion with the already xisting Options pattern.
> El 03/09/2014 02:53, "Andrew Phillips" <ap...@qrmedia.com> escribió:
>
> > Reviewing a couple of PRs [1, 2], I noticed a pattern for creating
> > subclasses for domain objects that need different attributes depending on
> > whether they should be created or updated.
> >
> > An example looks like
> >
> > SecurityGroup.createOptions().name("jclouds-test").description("jclouds
> > test security group").build())
> >
> > which seems like nice syntax to me. It's implemented by having a
> > "CreateOptions extends SecurityGroup" domain object subclass, whose Builder
> > is returned by createOptions().
> >
> > I added some comments to the PR because the main usage of classes named
> > *Options that I'm aware of in jclouds is as a parameter object to modify an
> > API call, not as a *domain* object variant.
> >
> > I'm a bit late to the party here, so apologies if I've missed a discussion
> > on this topic. I was wondering if this new naming risks confusing users,
> > and was curious to see if anyone has any suggestions...
> >
> > Regards
> >
> > ap
> >
> > [1] https://github.com/jclouds/jclouds-labs-openstack/pull/135
> > [2] https://github.com/jclouds/jclouds-labs-openstack/pull/132
> >

--
Andrew Gaul
http://gaul.org/

Re: Using *Options for domain objects?

Posted by Andrew Gaul <ga...@apache.org>.
I also prefer the builder pattern for options.  A lot of older code have
mutable options, with the NONE constant actually allowing mutations!

On Wed, Sep 03, 2014 at 09:36:19AM +0100, Ignasi Barrera wrote:
> I also like the syntax and think that's a pattern we could use in more
> places.
> 
> Regarding the naming I'm +1 to change the *Options to *Request or something
> else to avoid confusion with the already xisting Options pattern.
> El 03/09/2014 02:53, "Andrew Phillips" <ap...@qrmedia.com> escribió:
> 
> > Reviewing a couple of PRs [1, 2], I noticed a pattern for creating
> > subclasses for domain objects that need different attributes depending on
> > whether they should be created or updated.
> >
> > An example looks like
> >
> > SecurityGroup.createOptions().name("jclouds-test").description("jclouds
> > test security group").build())
> >
> > which seems like nice syntax to me. It's implemented by having a
> > "CreateOptions extends SecurityGroup" domain object subclass, whose Builder
> > is returned by createOptions().
> >
> > I added some comments to the PR because the main usage of classes named
> > *Options that I'm aware of in jclouds is as a parameter object to modify an
> > API call, not as a *domain* object variant.
> >
> > I'm a bit late to the party here, so apologies if I've missed a discussion
> > on this topic. I was wondering if this new naming risks confusing users,
> > and was curious to see if anyone has any suggestions...
> >
> > Regards
> >
> > ap
> >
> > [1] https://github.com/jclouds/jclouds-labs-openstack/pull/135
> > [2] https://github.com/jclouds/jclouds-labs-openstack/pull/132
> >

-- 
Andrew Gaul
http://gaul.org/

Re: Using *Options for domain objects?

Posted by Ignasi Barrera <na...@apache.org>.
I also like the syntax and think that's a pattern we could use in more
places.

Regarding the naming I'm +1 to change the *Options to *Request or something
else to avoid confusion with the already xisting Options pattern.
El 03/09/2014 02:53, "Andrew Phillips" <ap...@qrmedia.com> escribió:

> Reviewing a couple of PRs [1, 2], I noticed a pattern for creating
> subclasses for domain objects that need different attributes depending on
> whether they should be created or updated.
>
> An example looks like
>
> SecurityGroup.createOptions().name("jclouds-test").description("jclouds
> test security group").build())
>
> which seems like nice syntax to me. It's implemented by having a
> "CreateOptions extends SecurityGroup" domain object subclass, whose Builder
> is returned by createOptions().
>
> I added some comments to the PR because the main usage of classes named
> *Options that I'm aware of in jclouds is as a parameter object to modify an
> API call, not as a *domain* object variant.
>
> I'm a bit late to the party here, so apologies if I've missed a discussion
> on this topic. I was wondering if this new naming risks confusing users,
> and was curious to see if anyone has any suggestions...
>
> Regards
>
> ap
>
> [1] https://github.com/jclouds/jclouds-labs-openstack/pull/135
> [2] https://github.com/jclouds/jclouds-labs-openstack/pull/132
>