JSON (blob) as a scalar

I now disagree with myself too, lol.

Working from the json directive idea,

directive @json on FIELD_DEFINITION

In implementation, any field definition that has this directive is stored as a string, and requires a string input. In a perfect world, Dgraph would parse the string and check that not only it is JSON but that it adheres to the type on which the directive is applied.

type Foo {
  id: ID
  bars: [String] @json # this is a JSON string in the database. The input is a string, but output returns an array of strings or null if empty string or nil
  xyzzy: Baz! @json # this is stored as a JSON string in the database. The input requires a string, but output returns the type Baz defined below as a remote type.
  thud: Waldo @json # this is stored as a JSON string in the database. The input is a strong, but the output returns the type Waldo defined below as a remote type or null on empty string, nil
}

type Baz @remote { # type used to parse JSON for input checking and output
  qux: String
  quux: [String!]!
  quuz: Int
  corge: Float
  grault: DateTime
  garply: [Waldo]
}

type Waldo { # dual purpose type
  # Any @json field can use any other existing defined type for JSON input checking and output parsing
  # Since there is no @remote directive here, this will also be used as a regular stored type as well 
  # generating queries, mutations, and inputs. Note that querying this type would only get the types 
  # that are added through mutating this type and not added in via the Foo.thud as that stores a string 
  # and does not create a related node.
  id: ID
  fred: Point
  plugh: Baz
}
query {
  addFoo(input: [{
    bars: "[\"bar1\",\"bar2\"]"
    xyzzy: "{\"qux\":\"flux\",\"quux\":[\"core\",\"capacitor\"]}"
  }]) {
    foo {
      id
      bars
      xyzzy {
        qux
        quux
      }
    }
  }
}

Also on the implementation, some users may want to digest the JSON string in specific pieces like normal traversing, but instead following edges, it is parsing a string. Other users may want to retrieve the JSON string at once, and that could be supported with two fields in the generated type, one being the string unparsed, and the other being the parsed JSON.

data: {
  addFoo: {
    foo: [
      {
        id: "0xa",
        _bars: "[\"bar1\",\"bar2\"]",
        bars: ["bar1", "bar2"],
        _xyzzy: "{\"qux\":\"flux\",\"quux\":[\"core\",\"capacitor\"]}",
        xyzzy: {
          qux: "flux",
          quux: ["core", "capacitor"]
        }
      }
    ]
  }
}

This would also provide an official Dgraph work around to the following:


Problems to think through, How or if search would be available on these @json fields. I would opt to go for no @json @search on the first iteration just to get this concept out there and usable and then figure out if and how to allow searching through the JSON strings later.