Schema for Juju RPC messages

roger peppe roger.peppe at canonical.com
Thu Jul 28 11:47:30 UTC 2016


On 28 July 2016 at 12:12, Mark Shuttleworth <mark at ubuntu.com> wrote:
> On 28/07/16 12:57, roger peppe wrote:
>> On 28 July 2016 at 10:01, Mark Shuttleworth <mark at ubuntu.com> wrote:
>>> On 28/07/16 10:42, roger peppe wrote:
>>>> On 28 July 2016 at 01:07, Rick Harding <rick.harding at canonical.com> wrote:
>>>>> However, an API client in any language should never be auto generated.
>>>> This is a strong statement. I feel that, as with most things in
>>>> software engineering,
>>>> there's a trade-off. Personally I'm with Katherine "use the schema to
>>>> auto-generate the boilerplate, and then wrap that with a small shim
>>>> that is more crisp".
>>> Theres room for gray areas, and then there's times when it's better just
>>> to be crisp and clear. In this case, the crisp and clear house position
>>> is that we don't consider auto-generated code to be useful for anything
>>> other than auto-generated tests and auto-generated validation.
>>>
>>> In this example, you have the classic problem of how to deal with
>>> change. The auto-generated part will change in "brutal and blunt" ways,
>>> and your hand-crafted shim will need to know how to wrap it, which means
>>> you are constantly having to bridge the mental gap between what actually
>>> changed, how best to represent this idiomatically, and how the
>>> auto-generated blob represented the change.
>> I like this description. The auto-generated part
>> represents the reality of the network API. Having that auto-generated
>> part is really useful though, particularly in a statically typed language,
>> because the compiler will tell you where your nice hand-crafted shim
>> is now wrong.
>
> Agreed. This is the piece to get, as quickly and and simply as possible,
> behind the scenes.
>
>> And FWIW I do think that an auto-generated API can sometimes be very nearly as
>> nice as hand-generated code. For example, to take a concrete
>> example from github.com/juju/idmclient:
>>
>>     userInfo, err := client.User(&params.UserRequest{User: "bob"})
>>
>> is only a little less nice than the call one might manually craft:
>>
>>     userInfo, err := client.User("bob")
>>
>> It's a little more verbose, but just as clear to read, I think.
>
> Well, in the time it took to draft your email, you managed to design the
> handcrafted one. We both agree it's better, and I think we can both
> agree it was a bounded amount of work :)
>
> All those "little less nice" pieces add up to a messy world. Developer
> love to inhabit clean spaces with well articulated and considered,
> structural components. Let's give them that. We can.

I agree with that. But we're talking about sugar here, I think. Added sugar
doesn't *necessarily* imply a cleaner, less messy or better
articulated component
IMHO. That's one of the reasons I like Go - more layers of abstraction
can make things harder to reason about, although equally they can sometimes
really help.

In this world of limited development time, all else being equal, I
tend to prefer "no code at all" over a "bounded amount of code",
because all code implies potential bugs and ongoing maintenance
cost. Is that being too much of a lazy programmer? Quite possibly.
Where to draw the line between pragmatism and perfection is
something that's always on my mind, something that we're
all exploring all the time.

>> If a call isn't in a public API (true of 70% of entry points in the Juju API)
>> and there's only one or two invocations of that call in the entire code base
>> (true of many, perhaps most, of the calls), I'm wondering if it's
>> actually worth the extra effort (code + tests + additional ongoing maintenance)
>> to make those one or two lines of code that little bit prettier?
>
> Ever open up a Mac?
>
> Taste is a habit, not an outfit.

Heh, ever used the Mac APIs ? Not so clean in the *software*, unfortunately...

  cheers,
    rog.



More information about the Juju-dev mailing list