Your payload format is incomprehensible. Is there any documentation?

Your API requires the use of multiple levels of nested escaped JSON.

For example, when using create_item to set column values.

Individual column values may contain newlines and quotes, which need to be escaped.

The column_values argument needs to be converted to JSON, so its quotes and newlines need to be escaped, plus the ones in any individual column values need to be escaped a second time.

Then the mutation GraphQL document itself also need to be assigned to the query property of a JSON object qhich requires escaping the entire mutation document again.

There are multiple ways this nested escaping could be done. After much trial and error I have found that one format that works for create_item is this

{"query":"mutation {\r\n create_item (\r\n board_id: 6172423554, \r\n item_name: \"TEst9\", \r\n column_values: \"{\\\"note\\\":\\\"Newline\\\nStuff\\\\\\\"Quoted\\\\\\\"Stuff\\\"}\"\r\n ) \r\n {\r\n id\r\n }\r\n }\r\n"}

This form of nested escaping is not produced by the standard C# JSON libraries. They instead use \u0022 to escape quotes. Your API does returns an error if quotes are escaped using \u0022 so your API deserialization appears to be implementation specific.

Your example code is not very useful since it does not show what you actually need to construct, only the unescaped GraphQL.

The example provided here is painful enough, requiring quotes to be escaped with 7 backslashes at the most nested level, and this is just a trivial example. For more complex queries the payloads required are totally incompreshensible.

Does your API support payloads in a more reasonable format?

Is there any docmentation anywhere on what payload formats are supported regarding the multiple levels of nesting and escaping that are required?

Don’t build stuff as strings. Create objects. The column_values is just a JSON string of a column_values object. Start with an OBJECT with that structure then use JSON.stringify to create the string when ready.

Then for the request the only part that is an actual string is the graphql string, it goes in the query key of the request object. Use GraphQL variables instead of trying to nest your column_values string into the GraphQL string (why they won’t highlight this in the documentation is beyond me, they must think we’re too dumb or something?)

Google graphql variables, they will make your life 1000X easier, plus the SDK and API-SDK clients support them. Its easy. You would have a variable for your column_values then pass the column_values string as a variable key, and their server uses it at runtime.

1 Like

Agreeing with @anon29275264 here. It’s important that the api documentation and any code examples always use graphql variables so that new developers can start from a position of strength.

Concatenation of strings is the way of madness for JSON objects.

@dvdsmpsn Yes. This is something I’ve been calling out now for THREE years, that they are sabotaging devs unfamiliar with GraphQL - or confusing those who are. Nobody else documents their GraphQL API as creating a JSON body as a string and sending that string in the request. monday.com’s own graphql clients are set up to take a query string, variables, operation name - not a pre-formatted body as a string. YET thats what the documentation shows.

Btw did you know they have a new project for a new graphql client? API SDK

But none of the documentation for the actual API usage has been updated to reflect it - not that much of it uses the client anyway!

I’ve seen this recommendation several times over the years when other people have raised this issue, and respectfully I think it demonstrates a misunderstanding of the problem.

I’m not building my queries from strings.

As stated in my OP I am composing the query from objects, and if we were just talking about a single level of JSON containing quoted strings there would be no problem.

But we’re not. We are talking about multiple levels of nested JSON, and the problem is that there is no standard for how escaping should be done in that situation.

If I happen to be working in Node.js then I’d probably be using a JSON serialization library that has the same implementation specific nested escaping behaviour to the implementation of your API.

If however I’m working in C# or C++ then I’m probably working with a library that has different nested escaping behaviour.

I know you have a client SDK but I believe that’s only for Javascript clients, and from what I’ve seen your API works with the nested JSON that’s produced by Javascript clients anyway. So you have an SDK for the one language that doesn’t need it.

  1. There is no common standard for escaping nested JSON, different libraries do it differently.
  2. Your API does not accept all the possible variations of nested escaping.
  3. The variety of nested escaping that your API does accept is undocumented.
  4. Even knowing what the nested escaping requirements of your API are, if the libraries in the language I’m using don’t support that approach, then takes a lot of effort to create compatible payloads and with these multiple levels of nesting it’s very errorprone.

I read your post a bit more carefully Cody and took more notice of what you said about GraphQL variables. I understand what you meant by this now and you’re absolutely right. Using a GraphQL variable instead of inlining the column_values does actually eliminate one level of JSON nesting, which does make things a lot easier.

{
   "query": "mutation CreateItem($columnValues: JSON!) {\n  create_item (\n      board_id: 1234567890,\n      item_name: \"Name6\",\n      column_values: $columnValues) {\n    id\n  }\n}",
   "variables": {
        "columnValues": "{ \"note\": \"Some \\nmore \\\"quoted\\\" stuff\" }"
    }
}

It’s still a horrible API though and key points not being better documented is painful and time consuming.

@Neutrino has been put on ignore.