How to send multiple query variables using GraphQL Playground - json

If I have one variable named $external and one named $manifest, which should be JSON, how do I define them both as query variables in the GraphQL Playground?
{
"external": "name",
"manifest":
{
"some": "json",
}
}
This gives me an error: Expected String but found }``.
Yes, I am on the query variables tab, something that has caught out many people asking about how to pass a single query variable.

Avoid trailing commas in JSON (line 5 and originally line 6 as well)
{
"external": "name",
"manifest": {
"some": "json"
}
}
is valid JSON
You can test your JSON using jsonlint

Related

Creating valid JSON for container_definitions in Terraform

I’m creating an aws_ecs_task_definition resource. Within that resource, I need a container_definitions, which needs to be a JSON string. I’d like to add multiple secrets to that definition from a list of strings; [“var1”, “var2”].
The output I need looks like:
“secrets”: [
{
“name” = “var1”,
“valueFrom” = “arn:somestuffvar1”
},
{
“name” = “var2”,
“valueFrom” = “arn:somestuffvar2”
}
],
I have tried string interpolation and templatefile, this is the section from my .tftpl
  "secrets": [
   %{ for myvar in myvars ~}
    {
      "name": "${myvar}",
     "valueFrom”: “arn:somestuff${myvar}"
    }
    %{ endfor }
  ],
The problem is the commas. the above gives me
[
{
“name” = “var1”,
“valueFrom” = “arn:somestuffvar1”
}
{
“name” = “var2”,
“valueFrom” = “arn:somestuffvar2”
}
],
with no commas between the braces, if I add a comma, then i get a trailing comma
[
{
},
{
},
],
I’ve tried a zillion syntax variations, I’ve tried jsonencode on the interpolated string, I’ve tried stripping the trailing comma. Nothing gives me valid JSON. What am I missing?
The templatefile function documentation has a section specifically about Generating JSON or YAML from a template, which explicitly discourages using string templating to try to build valid JSON from string fragments like this.
Instead, you should use the jsonencode function as the entire definition of your template, and thus let Terraform be the one to worry about generating valid JSON syntax. You then only need to worry about writing an expression that describes the data structure that remote system expects.
In your case, a template generating a JSON object with just this "secrets" property would look like this:
${jsonencode({
secrets = [
for myvar in myvars : {
name = myvar
valueFrom = "arn:somestuff${myvar}"
}
],
})}
Notice that the entire template consists of a single interpolation sequence ${ ... } and the expression inside it is one big call to the jsonencode function, with the argument describing the data structure to serialize. Therefore inside that argument we're using normal Terraform expression syntax (like you'd write in a resource argument in a .tf file) rather than the special template interpolation/repetition syntaxes. In particular, the value of "secrets" is defined using a for expression.
With your { myvars = ["var1", "var2"] } template variables, this will produce a minified version of the following JSON structure, which I'm showing with manually-added indentation and newlines just so you can read it:
{
"secrets": [
{
"name": "var1",
"valueFrom": "arn:somestuffvar1"
},
{
"name": "var2",
"valueFrom": "arn:somestuffvar2"
}
]
}
I understand that you're only showing a fragment of the template here and so the above won't include all of the other properties included in your template, but hopefully you can see how to use Terraform expression syntax to describe those properties as Terraform object attributes too, so that the overall result of this template will be a valid JSON serialization of the total data structure.

How to get the results of a TDE in MarkLogic in RDF/JSON or Turtle format?

With any kind of Template Driven Extraction (TDE) in MarkLogic, how can I convert the results I get from the tde:node-data-extract function into RDF/JSON format? The JSON format returned by this method is not compliant with RDF/JSON, so I can't use it directly to insert triples into another database. In this case, I don't want to insert the triples into the same database that I'm applying the template against, I just want to use the template to create triples from XML data.
Here's an example of the JSON output that I get from the tde:node-data-extract function:
{
"document/pt/document/39627370": [{
"triple": {
"subject": "http://www.example.com/document/id/39627370",
"predicate": "http://www.example.com/typeOf",
"object": {
"datatype": "http://www.w3.org/2001/XMLSchema#string",
"value": "http://www.example.com/document"
}
}
},
{
"triple": {
"subject": "http://www.example.com/publisher/Oxford_University_Press",
"predicate": "http://www.example.com/typeOf",
"object": {
"datatype": "http://www.w3.org/2001/XMLSchema#string",
"value": "http://www.example.com/publisher"
}
}
}
}
}
Convert each "triple" property into a triple object using sem.triple(). Then serialize the array of sem.triple objects using sem.rdfSerialize().
https://docs.marklogic.com/sem.triple
https://docs.marklogic.com/sem.rdfSerialize
With the help from John and Mads, I found a slight variation that works really well assuming you're in the query console. $docs is any sequence of documents and $template is the TDE template.
let $jsontriples := tde:node-data-extract($docs, $template)
for $key in map:keys($jsontriples)
let $entry := map:get($jsontriples, $key)
return $entry["triple"]
This will return the triples automatically serialized into Turtle format in the query console Result tab, which you can switch to JSON or Text. I assume the answer from John is the most correct in a situation where the serialization is not automatically performed (e.g. when not using the query console).

Dynamically build json using groovy

I am trying to dynamically build some json based on data I retrieve from a database. Up until the opening '[' is the "root" I guess you could say. The next parts with name and value are dynamic and will be based on the number of results I get from the db. I query the db and then the idea was to iterate through the result adding to the json. Can I use jsonBuilder for the root section and then loop with jsonSlurper to add each additional section? Most of the examples I have seen deal with a root and then a one time "slurp" and then joining the two so wasn't sure if I should try a different method for looping and appending multiple sections.
Any tips would be greatly appreciated. Thanks.
{
"hostname": "$hostname",
"path": "$path",
"extPath": "$extPath",
"appName": "$appName",
"update": {"parameter": [
{
"name": "$name",
"value": "$value"
},
{
"name": "$name",
"value": "$value"
}
]}
}
EDIT: So what I ended up doing was just using StringBuilder to create the initial block and then append the subsequent sections. Maybe not the most graceful way to do it, but it works!
//Create the json string
StringBuilder json = new StringBuilder("""{
"hostname": "$hostname",
"path": "$path",
"extPath": "$extPath",
"appName": "$appName",
"update": {"parameter": ["""
)
//Append
sql.eachRow("""<query>""",
{ params ->
json.append("""{ "name": "params.name", "value": "params.value" },""");
}
)
//Add closing json tags
json.append("""]}}""")
If I got your explanation correctly and if the data is not very big (it can live in memory), I'd build a Map object (which is very easy to work with in groovy) and convert it to JSON afterwards. Something like this:
def data = [
hostname: hostname,
path: path,
extPath: extPath,
appName: appName,
update: [parameter: []]
]
sql.eachRow(sqlStr) { row ->
data.update.parameter << [name: row.name, value: row.value]
}
println JsonOutput.toJson(data)
If you're using Grails and Groovy you can utilize grails.converters.JSON.
First, define a JSON named config:
JSON.createNamedConfig('person') {
it.registerObjectMarshaller(Person) {
Person person ->
def output = [:]
output['name'] = person.name
output['address'] = person.address
output['age'] = person.age
output
}
}
This will result in a statically defined named configuration for the Object type of person. Now, you can simply call:
JSON.use('person') {
Person.findAll() as JSON
}
This will return every person in the database with their name, address and age all in one JSON request. I don't know if you're using grails as well in this situation though, for pure Groovy go with another answer here.

JSON for complex and simple data type

Im developing a WCF service that accepts JSON. My method signature accepts 2 parameters, a complex object and a simple type. For all intents and purposes below, assume "servicecredentials" has 2 properties, "username" and "password". I have valid JSON, but when I use a tool like postman I get the error "Expected to find an attribute with name 'type' and value 'object'. Found value 'array'.'"
How should this JSON be posted to the method?
<OperationContract()>
<WebInvoke(method:="POST")>
Function GetStuff(ByVal creds As servicecredentials, ByVal acctNum As String)
The JSON Im posting
[
{
"UserName": "someUSer",
"Password": "p#ssw0Rd"
},
{
"acctNum": "X12362"
}
]
The [] brackets indicate a JSON Array, the {} brackets indicate a JSON Object. If you encompass the array with the {} brackets it will be an object, which is what it seems to be looking for.
Example:
{
"data": [
{
"UserName": "someUSer",
"Password": "p#ssw0Rd"
},
{
"acctNum": "X12362"
}
]
}
The exact internal structure of the JSON depends on how the method will process the data. The error is simply stating that the JSON is not encompassed by an object.

Invalid JSON but validates on JSONLint

I have the following JSON which validates on JSONLint.com but when I pass it to JSON.parse() I get the error
SyntaxError: JSON.parse: unexpected character
...0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...
This is apparently the last "correct": line
var theJSON = JSON.parse({
"data": [
{
"wrong": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
"correct": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
},
{
"wrong": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
"correct": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
},
{
"wrong": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
"correct": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
},
{
"wrong": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
"correct": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
}
]
});
You, like many, have confused JavaScript's literal syntax with JSON. This happens a lot as JSON uses a subset of JavaScript's literal syntax so it looks a lot alike. JSON, however, is always a string. It is a serialized data scheme for porting data structures between langs/platforms.
Also confusing is that a string of JSON which has been output by any platform can be copied and pasted right into JavaScript and used. Again, this is because of the shared syntax. Having pasted such output right into JavaScript, however, one is no longer using JSON--they are now writing JavaScript in literal syntax. That is, unless, you pasted it between quotes and properly escaped the resulting string. But there's no sense in doing so as then it needs to be parsed in order to end up with what you already had.
JSON.parse() is a method for unserializing data which had been serialized into JSON. It expects a string because, well, JSON is a string. You're passing an object (in literal syntax). It does not need parsing...it is already the thing you want.
Wrapping your object literal in single quotes would make the code work, but it would be pointless to do so as the parse would simply result in what you already have.
Your code would be better written if you replaced the variable named theJSON with one named theObject and made it look as such:
var theObject = {
data: [
{
wrong: "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
correct: "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
},
{
wrong: "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
correct: "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
},
{
wrong: "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
correct: "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
},
{
wrong: "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
correct: "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
}
]
};
Whatever code wanted to use the parse result should be fine once you've done it.