What is a good GraphQL lib

I'm looking for decent lightweight GraphQL lib to use in Ignition.

Anyone else doing this?

When you say GraphQL lib for Ignition what do you mean?

A GraphQL client implementation that can work from Ignition scripting ... so a Python 2.7 lib would be my preference. And to be decent/lightweight I'd add pure Python and no required config files.

I would look for a Java library that you can run out-of-band on the GraphQL server you're trying to communicate to, generating consuming classes out-of-band, then dump them into a module (preferred) or the lib/ directory of the gateway, as described in this post dealing with Protobuf:

I have no control over server.

How much of a pain is going to be to get a client working with httpPost and other native and json libs?

Are there any other easy-button options? Perhaps some other middleware?

Sorry, 'on' was a poor choice of words. I'm not an expert in GraphQL, but I mean:

  1. Create a Java project using Maven or Gradle that consumes some Java GraphQL lib (e.g. Apollo.
  2. Point your Java project at your existing GraphQL server (assuming it supports introspection): 2. Add the GraphQL schema - Apollo GraphQL Docs to generate the Java classes you require.
  3. Attach those classes to Ignition, either by dumping the built .jar file into lib/ or building a custom module.

I don't think there is any 'free lunch' here. It looks like it should be pretty easy to deal with "raw" responses via system.net.httpClient: Serving over HTTP | GraphQL, but if you want any of the niceties a better client would offer you, it's going to take some doing.

Yea that seems like a lot of work to do a single freaking API call to say "here's the RFID tag I printed for product 12345"

I would go with this. You're right, it probably is not worth all the work to do all the jar/attaching to ignition etc, when realistically you just need to spend a little time figuring out how to parse a response.

The GraphQL response is always valid JSON, so not a huge deal. I'm sure some magic lib would do more of the heavy lifting for dealing with errors and whatnot.

However, the query itself is something that kind of looks like JSON, but it's not.

So what I needed to do was enclose the GraphQL query in a JSON string as a value to a key named query:

mutation = {"query": "mutation {createItemSet(input : %s){tracker_serials}}" % itemSetData}                  

Also needed to regexp out commas and quotes around key names supplied in the itemSetData.

# Step 1: Remove commas between dictionary items, but keep array-level commas
itemSetData = re.sub(r',(?=\s*"(?:\w+)":)', r'\n', itemSetData)

# Step 2: Remove quotes around keys only
itemSetData = re.sub(r'"(\w+)"\s*:', r'\1: ', itemSetData)

And finally the httpPost get's the job done:

contentType = "application/json"
auth = {"Authorization": tokenId}

postData = system.util.jsonEncode(mutation)
response = system.net.httpPost(url=uri, contentType=contentType,headerValues=auth,postData=postData,throwOnError=False)
responsedata = system.util.jsonDecode(response)

Exception handling removed for brevity.

1 Like

Seriously, don't use this function. They're going to be formally deprecated in 8.3.0, but in the meantime they obscure so many things about the HTTP relationship it's never worth it.

system.net.httpClient is a more performant, more debuggable, more powerful replacement. It'll also automatically handle the encoding and decoding of JSON for you (if the data param is a dictionary, the content-type is automatically set to application/json, and the response object has a json decode method built in):

auth = {"Authorization": tokenId}

client = system.net.httpClient()
response = client.post(uri, headers=auth, data=mutation)
responsedata = client.post(uri, headers=auth, data=mutation).json

One caveat: if this is a project library script (which it probably should be), you should instantiate the client instance outside any defined functions, e.g.

client = ...

def runGraphQlQuery(query):
    client.post()
    ....
5 Likes