X

The leading edge of scripting languages and Oracle Database brought to you by the Data Access Development team

Demo: GraphQL with Oracle Database SODA and node-oracledb

Christopher Jones
Senior Principal Product Manager

This is a GraphQL demo that stores data in an Oracle Database SODA collection. GraphQL is a query language for services. Oracle Database SODA is a NoSQL-like API for storing documents in Oracle Database. The demo follows on from my previous "Demo: GraphQL with Oracle Database and node-oracledb" which shows the same demonstration using relational tables and SQL queries. Read that post to learn about GraphQL and GraphQL queries. Also see the associated SODA presentation Getting Started with GraphQL APIs on Oracle Database with Node.js which shows some SODA features.

Demo prerequisites:

  • Oracle Database 18.3, or later

  • Oracle Client libraries 18.5 or 19.5, or later

Steps to run the demo:

  1. Download the source code from here and extract it with tar -xf graphql_oracle_soda.tgz

  2. Change to the graphql_oracle_soda directory, edit dbconfig.js and set your database schema credentials.

  3. Run npm install. This will install dependencies and run setup.js to create the SODA schema.

  4. Run npm start to start the GraphQL server.

  5. Load the URL http://localhost:3000/graphql

  6. In the browser, execute GraphQL requests shown in SAMPLE_QUERIES.txt

Since my previous blog discussed the behavior of the GraphQL inputs and outputs, let's look at the SODA implementation. In setup.js a collection is created:

const sodaCollectionName = "myBlogs";
let collection = await soda.openCollection(sodaCollectionName);

This method will actually open the collection if it already exists, so the next commands drop the collection so the demo can recreate it and run with a known, clean collection:

collection.drop();

await conn.execute(`begin
                     execute immediate 'drop sequence "mySequence"';
                     exception when others then
                       if sqlcode <> -2289 then raise; end if;
                     end;`);

The cleanup is in two parts because the collection that will be created uses a sequence for the document keys. While SODA will auto-create the sequence, the collection.drop() method doesn't automatically drop the created sequence.

The collection is then created using custom metadata:

const metaData =
  { "schemaName":          config.user.toUpperCase(),
    "tableName":          "myBlogs",
    "keyColumn":          { "name": "ID",
                            "assignmentMethod": "SEQUENCE",
                            "sequenceName": "mySequence" },
    "contentColumn":      { "name": "JSON_DOCUMENT",
                            "sqlType": "BLOB",
                            "compress": "NONE",
                            "cache": true,
                            "encrypt": "NONE",
                            "validation": "STANDARD" },
    "versionColumn":      { "name": "VERSION",
                            "method": "SHA256" },
    "lastModifiedColumn": { "name": "LAST_MODIFIED" },
    "creationTimeColumn": { "name": "CREATED_ON" },
    "readOnly": false};

collection = await soda.createCollection(sodaCollectionName, {metaData: metaData});

I only needed to specify the metadata because I wanted to change the default key generation from a SHA hash to be a sequence, to align with GraphQL's use of integers for identifiers.

The final part of the setup is creation of a couple of documents in the collection:

await collection.insertOne({"title": "Blog Title 1", "content": "This is blog 1"});
await collection.insertOne({"title": "Blog Title 2", "content": "This is blog 2"});

I could have done all the setup in a SQL file, but decided to be more Node.js-centric in this particular demo.

Let's look at the GraphQL code in graphql_oracle_soda.js. The GraphQL typedefs and resolvers are the same as the previous SQL example - as is the output from running the demo. The updated helpers that interact with the database are the interesting parts.

In the new SODA example, the helper to get one document aka blog is:

async function getOneBlogHelper(id) {
  let conn = await oracledb.getConnection();
  let soda = conn.getSodaDatabase();
  let collection = await soda.openCollection(sodaCollectionName);
  let document = await collection.find().key(id.toString()).getOne();
  let j = null;
  if (document) {
    let c = document.getContent();
    j = {id: id, title: c.title, content: c.content};
  }
  await conn.close();
  return j;
}

The SODA filter find() is used to find the SODA document with the requested id. The document content is extracted with getConection() and the document values are mapped to a JavaScript object returned back up via the GraphQL resolver. The other helpers are similarly straightforward.

This simple demo shows how to use some of Oracle's exciting SODA features. SODA APIs are available in a number of languages including Java and Python, letting you access your stored data from familar environments. If you do interesting things with SODA, let us know.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha