1

I have to edit regularly swagger JSON files to add a x-amazon-apigateway-integration property, files looks like:

{
  "openapi": "3.0.0",
  "info": {
    "version": "",
    "title": ""
  },
  "paths": {
    "/login": {
      "post": {
        "summary": "Login",
        "parameters": [
          {
            "required": false,
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "name"
          },
          {
            "required": false,
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "password"
          }
        ],
        "responses": {
          "400": {
            "description": "Invalid `name`"
          }
        },
        "x-amazon-apigateway-integration": {
            "uri": "${service-github}",
            "passthroughBehavior": "when_no_match",
            "httpMethod": "POST",
            "type": "aws_proxy"
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Empty": {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "title" : "Empty Schema",
        "type" : "object"
      }
    }
  }
}

I would like that summary, parameters, responses, and x-amazon-apigateway-integration to be folded for the whole file.

4
  • "summary" is a single line, so it can't be folded by itself... Do you mean fold the four others individually? Or fold the whole "post" block that contains them? – filbranden Jan 9 at 16:18
  • @D.BenKnoble actually, it does nothing. – GlinesMome Jan 9 at 16:20
  • @filbranden I mean, I want that all the children of a verb (post here), be on one line (folded or not), in order to quickly see if my key is missing. – GlinesMome Jan 9 at 16:22
  • @D.BenKnoble actually you are right, I had an old configuration interfering. – GlinesMome Jan 9 at 16:30
2

If you just want to fold the lines, you can do

:setlocal foldmethod=syntax foldenable

and then open/close as desired (:help folds).

In the comments, you mention putting a whole block on one line. There's an easy way to do that, too:

:global/"key":/normal! V%J

(e.g., with key as post).

What we are doing is Joining all the lines from the start of the block to the end by Visually selecting the lines between braces (%). This assumes the brace is on the same line as the key, which is usually the case with formatted JSON. (If the JSON is not formatted, :%!jq or :%!python -m json.tool will format the whole file.)

If you really want to check for missing keys, though, might I suggest writing a program? Python's json module can load JSON as dicts; there's also jq and gron for the command line. Almost every practical programming language supports JSON.

Here's a simple Python function to tell you which keys are missing from a JSON-like object; you can load a JSON file using json.load:

def missing_keys(obj, required_keys):
    return required_keys - obj.keys()

Some examples:

>>> obj = json.load(...)
>>> missing_keys(obj['paths']['/login']['post'], {})
set()
>>> missing_keys(obj['paths']['/login']['post'], {'responses'})
set()
>>> missing_keys(obj['paths']['/login']['post'], {'responses', 'my-bad-key'})
{'my-bad-key'}

Here's the equivalent with jq:

$ <... jq '["responses"] - (.paths."/login".post | keys)'
[]
$ <... jq '["responses", "my-bad-key"] - (.paths."/login".post | keys)'
["my-bad-key"]

Here's a version that outputs true/false if all required keys are there:

$ <... jq '(["responses"] - (.paths."/login".post | keys) | length) == 0'
true
$ <... jq '(["responses", "my-bad-key"] - (.paths."/login".post | keys) | length) == 0'
false

And lastly a version that is silent (except possibly stderr) and produces an error code, so can be used in a script's if:

$ <... jq 'if (["responses"] - (.paths."/login".post | keys) | length) == 0 then halt else halt_error(1) end'
$ echo $?
0
$ <... jq 'if (["responses", "my-bad-key"] - (.paths."/login".post | keys) | length) == 0 then halt else halt_error(1) end'
{"openapi":"3.0.0","info":{"version":"","title":""},"paths":{"/login":{"post":{"summary":"Login","parameters":[{"required":false,"schema":{"type":"string"},"in":"query","name":"name"},{"required":false,"schema":{"type":"string"},"in":"query","name":"password"}],"responses":{"400":{"description":"Invalid `name`"}},"x-amazon-apigateway-integration":{"uri":"${service-github}","passthroughBehavior":"when_no_match","httpMethod":"POST","type":"aws_proxy"}}}},"components":{"schemas":{"Empty":{"$schema":"http://json-schema.org/draft-04/schema#","title":"Empty Schema","type":"object"}}}}
$ echo $?
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.