Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Should IResource be "dumb" or smart?

See original GitHub issue

With the imminent merging of the interface branch, we currently have the following pattern which has become much clearer as part of that refactor:

  1. IResource. Represents an ARM resource in F#. Examples include:

An IResource is typically a record and has two members - a Resource Name (used to detect duplicate resources) and a unit -> obj function which knows how to create a “JSON ready” object containing only primitives ready for serialization.

  1. IResourceBuilder (and ResourceBuilder). Given a location, generate a list of IResource objects. ResourceBuilders are typically Records (typically with the postfix Config) and are wrapped by computation expressions builders (ignore the new ResourceBuilder approach for this discussion).

The pattern looks something like this:

So what?

ResourceBuilders are typically strongly typed, using discriminated unions and the like in order to construct types which, more or less, make illegal states unrepresentable. I say “more or less”, because there are some compromises that have made in order to keep the API as simple as possible from a consumption point of view (so that a minimal amount of types are needed when consuming any builders etc.).

The question is what constraints should the IResource make (before JSON serialization occurs)?

Option 1: Make them simple types with primitives only

This makes the mapping to the JSON-ready object very simple as the values are already primitives. The mapping instead happens in the IResourceBuilder at the point of generating the IResources. The “cost” of this is that if you want to use the same IResource type in multiple builders - for example, an IPAddress or a ServerFarm - you have to do the same mapping from a “smart” IResourceBuilder to a “dumb” IResource.

This is the current approach we now have in the latest version of master.

Option 2: Make them smarter types.

We make IResources smarter and put richer types on them. The cost of “dumbing down” happens right at the end, when we move to the JSON-ready object, and only then. The benefit of this approach is that the mapping to JSON is guaranteed to happen in a typesafe manner, and the mapping from IResourceBuilders to IResources will be relatively simple. The concern is that, assuming that we share typed because the IResource and IResourceBuilders, then the types that these records have should still live at a level that the consumer can easily get to - typically, just by opening Farmer.Resources (or even better, just Farmer). If these types instead live next to the IResource, users will need to fumble around knowing which namespaces to open, and the whole exercise of “ease of use” (which is a key driver behind Farmer) will be lost.

Appreciate this might seem like bikeshedding but nonetheless, if you’re interested in this, I’d welcome thoughts and feedback.

A good example is to look at ExpressRouteCircuit in the current master, which has been completely “dumbed down” as part of my merge into the new API cc: @ninjarobot . Previously it had stronger types.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:11 (10 by maintainers)

github_iconTop GitHub Comments

dburrisscommented, May 12, 2020

Oh great!

You forgot the sarcasm font 😛

dburrisscommented, May 7, 2020

Type-safety, building blocks, and seams

I do not think that giving users the option of using an IResource a problem, as long as we do provide higher-level constructs that do offer that ie. the Config and Builders. And maybe this is where we are diverging on view…

Currently, I see IResource as a raw persistence/transport implementation. It is a seam. Imagine for example we needed to support different ARM template versions and a builder would pick the IResource to output. Or Azure releases YARML 😛 Another desire for seems may come from a particularly tricky mapping. You might want to switch from a more testing Builder -> Json and split them Builder -> IResource; IResouce -> Json.

Viewing it this way makes IResource an implementation detail but one that we surface as a fairly first-class citizen purely because this is a library, not a framework (?). Maybe we are diverging in opinion here though, as I know you wanted to make Farmer opinionated.

What I am suggesting is let’s have the low-level building blocks, the clean type-safe wrappers and syntactic niceness around the building blocks of Azure, and then tighten the opinions in the “topology” layer.


The naming is a little confusing I think because we have 2 layers that represent the same thing. Maybe this is a tell and we need to simplify but for the sake of exploring the possible layers, let us push on.

Some suggestions for sharpening up the naming:

  • IResource: IArmResource brings it back to it being specifically for outputting the format for the resource in the ARM template. Other words that might fit to make this specific ResourceTemplate, ResourceSchema, …?
  • Config and Builder: Although I don’t hate Config, Builder or CE triggers me a bit as a way to refer to them collectively. Maybe collectively these are just a Resource but I think it would be less confusing if naming was easy to differentiate (not IResource and ResourceBuilder). I went on to the Azure site and see what they call it… so from an Arm concept, they call them resources of course. From an entry point though they call them Service or Product. I know Service is soooo overloaded… Just putting out some ideas here.
  • Typology: I do not think this is the right name for this. I am not sure we are clear on what we are aiming for here, and it can likely vary greatly. But I was thinking along the lines of where you were going with a Safe app @isaacabraham . I don’t know that anything that specific is needed. Configuring a system made up of multiple containers. What about Recipes? Examples – Web app with database – Static site – Batch processing

Making it simple to have the building blocks so people could create their own Recipes would be awesome. I mean that is already possible really but even in naming, we could show that this is the intent. I have worked in big dev departments were rolling out like this in a parameterized way would have been awesome.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is it better to be nice but dumb, or smart but mean?
Do intelligent people call themselves stupid, dumb etc.? 12,924 Views.
Read more >
Is it better to be smart or stupid? - PMC
Ernst Mayr, an evolutionary biologist, argued that lower, more stupid life forms are far better at survival than smart ones—as judged by ...
Read more >
How to be Smart in a World Full of Dumb People
Now, when I say dumb, I don't mean lacking intelligence. For the most part, humans can be very creative, intelligent, adaptable, resourceful ...
Read more >
Everyone is Gifted - Why I believe that adjectives like " ...
The answer is a resounding "No". In reality there are no permanently smart people nor permanently dumb people. fair-enough, some among us are ......
Read more >
Dumb, Smart or Intelligent? What's Really Relevant in the ...
Machines used to be dumb. They didn't make decisions, nor could they learn anything new. That is changing rapidly. Smart.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Post

No results found

github_iconTop Related Hashnode Post

No results found