Skip to content

Configuration System #297

@jasonkuhrt

Description

@jasonkuhrt

What

  • Configuration keeps coming up, see related (below) for examples

  • autocompletion and jsdoc should be optimized for

  • so many questions/ways we could do this...

  • function-object approach:

     app.settings({
       server: {
         experiments: {
           middleware: true,
         },
       },
     })		
  • object approach:

     app.settings.server.experiments.middleware = true
     app.settings.server.logger.level = 'debug'
     app.settings.experiments.server.middleware = true
     app.settings.plugins.prisma.crud.relations.createable = false
  • function-object and object approaches could be combined

  • some screenshot / dx observations:

    • vscode gives awkward autocomplete for objects when curly braces are broken across lines.

      image

    • vscode/ts does not give a preview of the settings one can set on param preview (is case for both type = ... and interface = ...)

      Screen Shot 2020-01-16 at 8 30 30 PM
    • user has no autocomplete with object unless they know how to summon the autocomplete with hotkey (ctrl-space). Even if they know, unclear how well that fits into their flow (e.g. they only know how via menu or have awkward bindings or are on a friend's computer with different customizations, ...)

      Screen Shot 2020-01-16 at 8 30 41 PM
    • errors can be visually loud

      Screen Shot 2020-01-16 at 8 51 52 PM
    • error information can be non-trivial

      image

    • working with object properties leads to clean autocomplete compared to above:

      image

  • function-object approach however is JS idiomatic and a succinct experience

  • to keep the mental model simple, app.settings should make its data readable in plain form:

     	console.log('the port is %s', app.settings.server.port)
  • so even with function-object for writes there would still be object for reads

  • at that point, might as well permits writes and leave it up as a style decision? object read/write is the most "basic" but the function-object is there for sugar

about hierarchy

app.settings.<component>.*
app.settings.plugins.<plugin>.*
app.settings.logger.*
app.settings.server.*
app.settings.db.*
app.settings.plugins.prisma.*

Sometimes duplicated read/write fields under different paths might be nice. Take the experiments system for example:

app.settings.<component>.experiments.*
app.settings.experiments.<component>.*

Basically When something could be distributed or centralized, we should do both so that the user doesn't have to remember.

  • settings would need to be applied before e.g. nexus schema
  • because e.g. app.settings.plugins.prisma might affect how nexus-prisma will behave during nexus schema time
  • this starts to feel complex when realizing we're offering up an api for settings where user could do pretty well anything... e.g. they can order their code how they want
  • we'll just have to see if insurmountable issues arise or not
  • absolute worst case would be an e.g. settings.ts convention

Related

Places where need for config has come up:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions