2

Say we have an API that accepts a list of objects. Something like:

{
    "family": "Does",
    "contact_details": [
        {
            "name": "John",
            "email": "john@example.com"
        },
        {
            "name": "Jane",
            "email": "jane@example.com"
        }
    ]
}

Say you then wanted to add a CLI for this, how would one structure the CLI parameters? The API is a nested API, but CLI arguments are by design flat.

I can think of two patterns, neither of which I like:

  1. Expose a new CLI to create these nested entries, and then use those to create the top-level object:

    $ foo contact create --name "John" --email "john@example.com"
    f53539be-205c-11eb-adc1-0242ac120002
    $ foo family create --name "Does" --contact f53539be-205c-11eb-adc1-0242ac120002
    

    I think this could work quite nicely if the API was well designed and allowed creation of these things as separate resources. Without that though, you'd have to somehow cache these fake resource locally, which sounds icky.

  2. Use CSV-style key-value pairs:

    $ foo family create --name "Does" --contact name=John,email=john@example.com
    

    This is hard to document and hard to use (no easy auto-completion, for one), particularly as the complexity of the object in the list grow.

Are there any other designs common across *nix-style CLIs that I'm missing?

stephenfin
  • 171
  • 4
  • 1
    Nothing says you can't require multiple instances of a named argument and/or that they appear in a certain order or paired up. It isn't common because there isn't usually such a requirement. But e.g., `foo family create --name "Does" -cJohn -ejohn@example.com -cJane -ejane@example.com`. Don't forget to have an argument that lets you specify a file containing your json or whatever too - `foo family create -fdoe-family.json`. – davidbak Nov 06 '20 at 18:31

1 Answers1

7

CLI programs often resort to file or stdin based input when data is more complex than can be properly communicated via command line. For example, GNU grep allows multiple patterns on the command line, but also supports passing patterns in a file.

If your data is nested as in your example, writing it down within the limitations of the command line is error-prone and tedious. Representations of object structures that are better suited to manual editing such as YAML or TOML might be much easier to work with.

Hans-Martin Mosner
  • 14,638
  • 1
  • 27
  • 35