Skip to content

Latest commit

 

History

History
223 lines (177 loc) · 4.78 KB

File metadata and controls

223 lines (177 loc) · 4.78 KB

StructureQL

Structure QL, not to be confused with Structured Query Language (SQL) (Could not come up with a better name for now). Is a small frame work targeted at enabling REST/HTTP framworks to ease implementation of partial returns based on structured data, currently aimed specifically at JSON.

Examples

Given the following JSON:

{
    "id": "GPL-2.0",
    "identifiers": [
      {
        "identifier": "GPL-2.0",
        "scheme": "DEP5"
      },
      {
        "identifier": "GPL-2.0",
        "scheme": "SPDX"
      },
      {
        "identifier": "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
        "scheme": "Trove"
      }
    ],
    "links": [
      {
        "note": "tl;dr legal",
        "url": "https://tldrlegal.com/license/gnu-general-public-license-v2"
      },
      {
        "note": "Wikipedia page",
        "url": "https://en.wikipedia.org/wiki/GNU_General_Public_License"
      },
      {
        "note": "OSI Page",
        "url": "https://opensource.org/licenses/GPL-2.0"
      }
    ],
    "name": "GNU General Public License, Version 2.0",
    "other_names": [],
    "superseded_by": "GPL-3.0",
    "keywords": [
      "osi-approved",
      "popular",
      "copyleft"
    ],
    "text": [
      {
        "media_type": "text/plain",
        "title": "Plain Text",
        "url": "https://www.gnu.org/licenses/gpl-2.0.txt"
      },
      {
        "media_type": "text/html",
        "title": "HTML",
        "url": "https://www.gnu.org/licenses/gpl-2.0-standalone.html"
      }
    ]
}

Using DotJEM.StructureQL.Json, we can query into the document with the following queries:

**Return the entire document: **
** or {**}


Return only top level primitive fields:
* or {*}

Code

JObject result = json.Query("*");

Result:

{
    "id": "GPL-2.0",
    "name": "GNU General Public License, Version 2.0",
    "superseded_by": "GPL-3.0"
}

Return specific named properties:
{id,name}

Code

JObject result = json.Query("{id,name}");

Result:

{
    "id": "GPL-2.0",
    "name": "GNU General Public License, Version 2.0"
}

Return id, name and all identifiers:
{id,name,identifiers:*}, {id,name,identifiers:**}, {id,name,identifiers:{*}} or {id,name,identifiers:{**}}
Because each of the identifier objects only has top level promitives, both * and ** works the same here, if there was nested properties and we wanted the full identifier objects we either need to use **/{**} or query specifically for properties and child properties of the object.

Code

JObject result = json.Query("{id,name,identifiers:*}");

Result:

{
    "id": "GPL-2.0",
    "name": "GNU General Public License, Version 2.0",
    "identifiers": [
      {
        "identifier": "GPL-2.0",
        "scheme": "DEP5"
      },
      {
        "identifier": "GPL-2.0",
        "scheme": "SPDX"
      },
      {
        "identifier": "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
        "scheme": "Trove"
      }
    ]
}

Return id, name and a range of identifiers:
{id,name,identifiers:[0..1]*}, {id,name,identifiers:[0..1]**}, {id,name,identifiers:[0..1]{*}} or {id,name,identifiers:[0..1]{**}}
If we know a property is an array, we can add [<from>..<to>] in front of the query on that object to select only a number of items in the array. Both from and to are optional, where [1..] selects elements from index 1 and up, [..1] selects element 0 and 1 and [..] means all and is redundant to just leaving it out.

Code

JObject result = json.Query("{id,name,identifiers:[0..1]*}");

Result:

{
    "id": "GPL-2.0",
    "name": "GNU General Public License, Version 2.0",
    "identifiers": [
      {
        "identifier": "GPL-2.0",
        "scheme": "DEP5"
      },
      {
        "identifier": "GPL-2.0",
        "scheme": "SPDX"
      }
    ]
}

Return id, name and links with only the url property
{id,name,links:{url} }

Code

JObject result = json.Query("{id,name,links:{url} }");

Result:

{
    "id": "GPL-2.0",
    "name": "GNU General Public License, Version 2.0",
    "links": [
      {
        "url": "https://tldrlegal.com/license/gnu-general-public-license-v2"
      },
      {
        "url": "https://en.wikipedia.org/wiki/GNU_General_Public_License"
      },
      {
        "url": "https://opensource.org/licenses/GPL-2.0"
      }
    ]
}

All the above queries the objects via an extension method, when querying multiple objects its worth reusing the parsed query so it's not parsed over and over again:

Code

IStructureQuery query = StructureQL.Parse("{id,name,links:{url} }");
var result = listOfJObjects.Select(json => json.Query(query));