XQuery GraphQL service for Marklogic
XQuery implementation of the GraphQL specification, largely inspired from the javascript library GraphQL.js
This library provides a graphql service fully featured with validation, execution and introspection.
Subscription is not yet supported.
To use the library as a dependency, you will need to have access to an instance of Marklogic, either local or remote, where you have sufficient permissions to deploy schemas, modules and load data.
In addition, if you want to deploy the library as an independent application (to run the unit tests and/or contribute to the development) you will also need to have sufficient permission to deploy a new application.
To expose a GraphXQL service in your project, the recommended way is to import the library as a Gradle dependency.
Assuming you're using ml-gradle, you can easily add a graphQL service to your application.
As this project hasn't been published to the jcenter repository yet, you'll first need to publish a copy of this project to your local Maven repository, which defaults to ~/.m2/repository.
To do so, clone this repository and run the following command in the project's root directory:
./gradlew publishToMavenLocal -Pversion=1.0.0-SNAPSHOT
You can verify that the artifacts were published successfully by looking in the ~/.m2/repository/graph/x/ql/graphXql directory.
Now that you've published GraphXQL locally, you can add it to your own application. You just need to add
the following to your build.gradle
(again, this depends on using ml-gradle).
First, in the repositories block, make sure you have your local Maven repository listed:
repositories {
mavenLocal()
}
And then just add the following to your dependencies block:
dependencies {
mlBundle "graph.x.ql:graphXql:1.0.0-SNAPSHOT"
}
This assumes that the version of the artifacts you published above is 1.0.0-SNAPSHOT. You can find the version number by looking at the version property in gradle.properties in your cloned copy of GraphXQL.
Next, run the following commands:
./gradlew mlReloadSchemas
This will deploy the XSD schemas required to define the types used internally by the GraphQL library
./gradlew mlReloadModules
This will load all modules, including those coming from the GraphQL library, including the graphql service as a Marklogic Rest extension 😄
./gradlew mlLoadData
This deploys the introspection graqhXql schema. You will also need to run this command when you create or modify your own graqhXql schema. (see below)
To work, a GraphXQL service relies on a GraphXQL schema, i.e. the XML equivalent of the regular GraphQL schema based on the GraphQL SDL.
Thus you need to define a GraphXQL XML schema to expose the types supported by your endpoint. Validity of the schema is checked against SDL.xsd
The library repository includes a sample schema schema.xml
inspired from the StarWars schema used in the GraphQL.js library
All you have to do is to implement the resolvers which will "produce" your project specific data according to the schema.xml
mentionned above and export them in the module export.xqy
which is used to connect your project specific implementation to the generic GraphXQL library.
An example implementation of resolvers
can be found in the library repository.
Once deployed, you can test the service by sending a valid graphQL query to the service endpoint
xquery version "1.0-ml";
declare namespace http="xdmp:http";
declare variable $graphXql-endpoint-uri := "http://localhost:8152/LATEST/resources/graphXql";
let $query :=
'{
person(id: 1) {
name
friends {
name
}
}
}'
let $payload := object-node {
"query": $query
}
return xdmp:http-post(
$graphXql-endpoint-uri,
<options xmlns="xdmp:http">
<headers>
<content-type>application/json</content-type>
</headers>
<authentication method="digest">
<username>admin</username>
<password>admin</password>
</authentication>
</options>,
$payload)
If everything is setup correctly, the above code should return
<response xmlns="xdmp:http">
<code>200</code>
<message>OK</message>
<headers>
<content-type>application/json; charset=UTF-8</content-type>
<server>MarkLogic</server>
<content-length>63</content-length>
<connection>Keep-Alive</connection>
<keep-alive>timeout=5</keep-alive>
</headers>
</response>
{
"data": {
"person": {
"name": "Luke",
"friends": {
"name": "Daisy"
}
}
}
}
When working with a client application such as GraphiQL or Insomnia, you should also benefit from the introspection and have access to all the types exposed by your service.
To contribute to the project:
First, get the latest version of the project.
git clone https://github.com/lonesloane/graphxql.git
Review the content of the file gradle-local.properties
and if needed update the targeted ports for the main application and the unit-test application.
You should also review the user and password used for the deployment.
Next, deploy the application.
cd graphxql/
./gradlew mlDeploy -i
This will create a dedicated GraphXQL application server on your local Marklogic instance as well as the unit-tests application on a separate port.
To run the unit tests, either open the unit-test web application in your browser, or run the following command:
./gradlew mlUnitTest -i
While working locally on the library, you might also want to test its integration in another project.
To do so, publish the library to you local Maven repository using:
./gradlew publishToMavenLocal -i
Then, in the project using the library as a dependency, run the following command before reloading the modules and/or the schemas
./gradlew mlInstallPlugins -i
When you are satisfied with the changes on your local environment, you can choose to deploy a new version on a centralized Maven repository:
gradlew publish -Pversion=YOUR_VERSION_NUMBER -i
as defined in the build.gradle
file:
publishing {
repositories {
maven {
url = { "http://url.to.your.maven/repository" }
credentials {
username "$mavenUser"
password "$mavenPassword"
}
}
}
publications {
pluginPublication (MavenPublication) {
artifactId "graphXql"
artifact bundleJar
}
}
}
This library is still in a fairly early stage, if you'd like to contribute, please fork the repository and use a feature branch.
Pull requests are warmly welcome.
- Fork it (https://github.com/lonesloane/GraphXQL/fork)
- Create your feature branch (
git checkout -b feature/fooBar
) - Commit your changes (
git commit -am 'Add some fooBar'
) - Push to the branch (
git push origin feature/fooBar
) - Create a new Pull Request
- Project homepage: https://github.com/lonesloane/graphxql/
- Repository: https://github.com/lonesloane/graphxql/
- Issue tracker: https://github.com/lonesloane/graphxql/issues
The code in this project is licensed under MIT license - see the LICENSE file for details
- A lot of inspiration was taken from the GraphQL.js implementation, especially the parser and the validation rules.