{"id":16920733,"url":"https://github.com/dherault/semantic-graphql","last_synced_at":"2025-08-11T17:34:34.729Z","repository":{"id":65494370,"uuid":"96418356","full_name":"dherault/semantic-graphql","owner":"dherault","description":"Create GraphQL schemas from RDF ontologies","archived":false,"fork":false,"pushed_at":"2024-03-25T14:52:22.000Z","size":196,"stargazers_count":88,"open_issues_count":4,"forks_count":13,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-05-02T00:56:47.399Z","etag":null,"topics":["graphql","rdf","semantic-data"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dherault.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-07-06T10:24:29.000Z","updated_at":"2024-03-28T10:12:32.000Z","dependencies_parsed_at":"2024-03-30T21:46:37.510Z","dependency_job_id":null,"html_url":"https://github.com/dherault/semantic-graphql","commit_stats":{"total_commits":66,"total_committers":3,"mean_commits":22.0,"dds":"0.045454545454545414","last_synced_commit":"eb14a115e619b84d89773a73c52cfeeea0704176"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dherault%2Fsemantic-graphql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dherault%2Fsemantic-graphql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dherault%2Fsemantic-graphql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dherault%2Fsemantic-graphql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dherault","download_url":"https://codeload.github.com/dherault/semantic-graphql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221673983,"owners_count":16861754,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphql","rdf","semantic-data"],"created_at":"2024-10-13T19:49:25.419Z","updated_at":"2024-10-27T12:14:31.760Z","avatar_url":"https://github.com/dherault.png","language":"JavaScript","readme":"# Semantic GraphQL\n\n[![npm version](https://badge.fury.io/js/semantic-graphql.svg)](https://www.npmjs.com/package/semantic-graphql)\n[![Build Status](https://travis-ci.org/nelson-ai/semantic-graphql.svg?branch=master)](https://travis-ci.org/nelson-ai/semantic-graphql)\n[![Coverage Status](https://coveralls.io/repos/github/nelson-ai/semantic-graphql/badge.svg?branch=master)](https://coveralls.io/github/nelson-ai/semantic-graphql?branch=master)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](#contributing)\n\nSemantic GraphQL provides an API to convert any [RDF](https://www.w3.org/TR/rdf11-primer/), [RDFS](https://www.w3.org/TR/rdf-schema/) and [OWL](http://www.w3.org/TR/owl-primer)-based ontologies into [GraphQL](http://graphql.org/) objects.\n\nThe library does not deal with data, only with terminology. Therefore resolving data/resources is up to you.\n\n**Table of contents:**\n\n- [Installation](#installation)\n- [Getting started](#getting-started)\n- [SemanticGraph API](#semanticgraph-api)\n- [Resolvers](#resolvers)\n- [Overriding default values](#overriding-default-values)\n- [Using Relay](#using-relay)\n- [OWL features roadmap](#owl-features-roadmap)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Installation\n\nRuns on Node v6 or higher.\n\n`npm install semantic-graphql --save`\n\n## Getting started\n\nSemantic-graphql makes no assumption about the shape of your data and only passes it around. You have to provide six functions to resolve it in different ways. See the [resolvers section](#resolvers).\n\n```js\nconst resolvers = { /* Choose how to resolve data */ };\n```\n\nOnce your resolvers are written you can create a SemanticGraph. In the graph all the triples defining RDF, RDFS and OWL are included by default.\n\n```js\nconst SemanticGraph = require('semantic-graphql');\n\nconst _ = new SemanticGraph(resolvers, config);\n```\n\nNow you can add your own triples. Only statements defining your terminology (classes + properties) will be used, so you shouldn't add your individuals as it will only consume memory.\n\n```js\n_.addTriple({\n  subject: 'http://foo.com#MyClass',\n  predicate: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type',\n  object: 'http://www.w3.org/2002/07/owl#Class',\n});\n\n// From a string or a file. Multiple formats are available.\n_.parse(string);\n_.parseFile('/path/to/ontology.ttl');\n```\n\nWhen Semantic-graphql translates a rdf:Property to a GraphQLFieldConfig, the resulting type will be wrapped in a GraphQLList unless the property is a owl:FunctionalProperty. Therefore you may have to do some adjustments in order to prevent that. Almost anything can be overriden, see the [override section](#overriding-default-values).\n\n```js\n// We do not want rdfs:label to resolve arrays\n_['http://www.w3.org/2000/01/rdf-schema#label'].isGraphqlList = false;\n```\n\nNow you can start building your GraphQL schema however you want.\n\n```js\nconst schema = new GraphQLSchema({\n  query: new GraphQLObjectType({\n    name: 'Query',\n    fields: {\n      myField: {\n        // GraphQL objects are created on demand using the API\n        type: _.getObjectType('http://foo.com#MyClass'),\n        resolve: /* ... */,\n      },\n      resource: {\n        // The rdfs:Resource interface allows you to query any data\n        type: _.getInterfaceType('http://www.w3.org/2000/01/rdf-schema#Resource'),\n        args: {\n          id: { type: new GraphQLNonNull(GraphQLString) },\n        },\n        resolve: /* ... */,\n      },\n    },\n  }),\n});\n```\n\nHave a look at the [examples folder](examples/) to see a complete setup.\n\n## SemanticGraph API\n\n```\nclass SemanticGraph {\n  constructor(resolvers: Resolvers, config: ?SemanticGraphConfig),\n  nTriples: number,\n  # The semantic data is stored directly on the graph\n  [subject: Iri]: { [predicate: iri]: Array\u003cobject: string\u003e },\n  # Public methods:\n  addTriple: AddTripleFn,\n  parse: ParseFn,\n  parseFile: ParseFileFn,\n  getObjectType: GetObjectTypeFn,\n  getInterfaceType: GetInterfaceTypeFn,\n  getEdgeType: GetEdgeTypeFn,\n  getConnectionType: GetConnectionTypeFn,\n  addFieldOnObjectType: AddFieldOnObjectTypeFn,\n  extendFieldOnObjectType: ExtendFieldOnObjectTypeFn,\n  # When the relay option is on:\n  nodeField: GraphQLFieldConfig,\n  nodeInterface: GraphQLInterfaceType,\n}\n\ntype SemanticGraphConfig = {\n  prefixes?: PrefixConfig,\n  # Activates the Relay features\n  relay?: boolean,\n  # Your reprefered locale when inferring names and descriptions from rdfs:label and rdfs:comment\n  locale?: string = 'en',\n  # Prevents the id field to be automatically added to every GraphlQLFieldConfigMap\n  preventIdField?: boolean,\n}\n```\n\nTo prevent GraphQL names collisions, you can edit the name directly (see the [override section](#overriding-default-values))\nor specifify prefixes for ontology namespaces.\nThe names of the generated GraphQL objects will be prefixed.\nRDF, RDFS and OWL ontologies are by default prefixed with \"rdf\", \"rdfs\" and \"owl\".\nSo a fragment on rdfs:Resource should be \"on RdfsResource\".\n\n```\ntype PrefixConfig = {\n  [prefix: string]: Iri,\n}\n\n# Must represent a valid IRI\ntype Iri = string\n```\n\n### addTriple\n\n```\ntype AddTripleFn(triple: Triple) =\u003e undefined\n\ntype Triple = {\n  subject: Iri,\n  predicate: Iri,\n  object: Iri | string,\n}\n```\n\nAppends a triple to the graph. No-op if the subject or predicate IRI is invalid, or if the triple already exists.\n\n### parse\n\nDeprecated\n\n### parseFile\n\nDeprecated\n\n### getObjectType\n\n```\ntype GetObjectTypeFn = (classIri: Iri) =\u003e GraphQLObjectType\n```\n\nReturns the GraphQLObjectType corresponding to a given individual of rdfs:Class or its sub-classes (like owl:Class). Throws if the IRI is not found in the graph.\n\n### getInterfaceType\n\n```\ntype GetInterfaceTypeFn = (classIri: Iri) =\u003e GraphQLInterfaceType\n```\n\n### getEdgeType\n\n```\ntype GetEdgeTypeFn = (classIri: Iri) =\u003e ?RelayEdgeType\n```\n\nReturns a value only when the `relay: true` option is on.\n\n### getConnectionType\n\n```\ntype GetConnectionTypeFn = (classIri: Iri) =\u003e ?RelayConnectionType\n```\n\nReturns a value only when the `relay: true` option is on.\n\n### addFieldOnObjectType\n\n```\ntype AddFieldOnObjectTypeFn = (\n  classIri: Iri,\n  fieldName: string,\n  graphqlFieldConfig: GraphQLFieldConfig\n) =\u003e Iri\n```\n\nAdds a custom field on the GraphQLObjectType and GraphQLInterfaceType representing a class.\nThrows if \"classIri\" is not found in the graph.\nReturns a random IRI referencing the new virtual rdf:Property.\n\n### extendFieldOnObjectType\n\n```\ntype AddFieldOnObjectTypeFn = (\n  classIri: Iri,\n  propertyIri: Iri,\n  graphqlFieldConfig: PseudoGraphQLFieldConfig\n) =\u003e undefined\n```\n\nSimilar to overriding a field using `_['http://foo.com/someProperty'].graphqlFieldConfigExtension = /* ... */` but only for a particular class, not for all of the classes on the property's domain.\nA `PseudoGraphQLFieldConfig` is just a `GraphQLFieldConfig` where every key is optional. The other keys will be infered.\nThrows if \"classIri\" is not found in the graph.\n\n## Resolvers\n\nResolvers are functions needed to resolve data. You have to code them.\n\n```\ntype Resolvers = {\n  resolveSourceId: ResolveSourceIdFn,\n  resolveSourceTypes: ResolveSourceTypesFn,\n  resolveSourcePropertyValue: ResolveSourcePropertyValueFn,\n  resolveResource: ResolveResourceFn,\n  resolveResources: ResolveResourcesFn,\n  resolveResourcesByPredicate: ResolveResourcesByPredicateFn,\n}\n\ntype ResolverOutput\u003cx\u003e = x | Array\u003cx\u003e | Promise\u003cx\u003e | Promise\u003cArray\u003cx\u003e\u003e\n```\n\n### resolveSourceId\n\nGiven a source, resolve its id.\n\n```\ntype ResolveSourceIdFn = (\n  source?: any,\n  context?: any,\n  info?: GraphQLResolveInfo\n) =\u003e ?ID | ?Promise\u003cID\u003e\n```\n\nMust be sync if you use Relay.\nSee [`globalIdField`'s source code](https://github.com/graphql/graphql-relay-js/blob/master/src/node/node.js#L107)\n\n### resolveSourceTypes\n\nGiven a source, resolve its rdf:type. Can be a single IRI since its super-classes will be infered.\n\n```\ntype ResolveSourceTypesFn = (\n  source?: any,\n  info?: GraphQLResolveInfo\n) =\u003e ResolverOutput\u003cclass: Iri\u003e\n```\n\n### resolveSourcePropertyValue\n\nGiven a source and the IRI of a predicate, resolve the objects for that source and predicate.\n\n```\ntype ResolveSourcePropertyValueFn = (\n  source?: any,\n  propertyIri?: Iri,\n  context?: any,\n  info?: GraphQLResolveInfo\n) =\u003e ?ResolverOutput\u003cany\u003e\n```\n\n### resolveResource\n\nGiven the IRI of a resource, resolve a \"source\" for other resolvers to use. You can either return the resource IRI to pass around as source, or fetch all the predicates/objects for that subject and return an object.\n\n```\ntype ResolveResourceFn = (\n  resourceIri?: Iri,\n  context?: any,\n  info?: GraphQLResolveInfo\n) =\u003e ?ResolverOutput\u003cany\u003e\n```\n\n### resolveResources\n\nSame as `resolveResource` but with an array of IRIs.\n\n```\ntype ResolveResourcesFn = (\n  resourceIris?: Array\u003cIri\u003e,\n  context?: any,\n  info?: GraphQLResolveInfo\n) =\u003e ?ResolverOutput\u003cany\u003e\n```\n\n### resolveResourcesByPredicate\n\nGiven a array of possible rdf:type, a predicate and an object, resolve the subjects matching that pattern.\n\n```\ntype ResolveResourcesByPredicateFn = (\n  typeIris?: Array\u003cIri\u003e,\n  predicateIri?: Iri,\n  value?: any,\n  context?: any,\n  info?: GraphQLResolveInfo\n) =\u003e ?ResolverOutput\u003cany\u003e\n```\n\n## Overriding default values\n\nTo override anything there is no method: you directly set the library's internals.\n\n```js\n_['http://the.resource.to/be#altered'].key = value;\n```\n\nIf \"key\" is already present, the library will use the underlying value and won't try to create it.\n\n| Resource type | key | value type |\n| ------------- | --- | ---------- |\n| any | graphqlName | String |\n| any | graphqlDescription | String |\n| class | graphqlFieldConfigMap | GraphQLFieldConfigMap |\n| class | graphqlObjectType | GraphQLObjectType |\n| class | graphqlInterfaceType | GraphQLInterfaceType |\n| class | relayConnectionDefinitions | { edgeType, connectionType } |\n| property | isGraphqlList | Boolean |\n| property | isRelayConnection | Boolean |\n| property | graphqlFieldConfig | GraphQLFieldConfig |\n| property | graphqlFieldConfigExtension | partial GraphQLFieldConfig, to modify only parts of it |\n| property | shouldAlwaysUseInverseOf | Boolean |\n| property | shouldNeverUseInverseOf | Boolean |\n\nNote that the following overrides must be performed *before* invoking `getObjectType` or `getInterfaceType` or `getEdgeType` or `getConnectionType` since those methods create the GraphQL objects you want to override.\n\nExamples:\n```js\n_['http://foo.com#worksForCompany'].graphqlName = 'company';\n// Now the field name for foo:worksForCompany will be 'company'\n\n// Partial modifications to fields are achieved using\n_['http://foo.com#someOtherProperty'].graphqlFieldConfigExtension = {\n  args: /* Look Ma', arguments! */\n  resolve: customResolveFn,\n};\n\n// Completly overriding a GraphQLObject can be done with\n_['http://foo.com/MyClass'].graphqlObjectType = new GraphQLObjectType({ /* ... */});\n```\n\n## Using Relay\n\nBy using the `relay: true` option:\n\n- The `_.nodeField` and `_.nodeInterface` object are available\n- The `_.getConnectionType` and `_.getEdgeType` methods are available\n- All ObjectTypes exhibit the Node interface\n- The id field is a globalIdField\n\nSee the [Relay example](examples/relay).\n\n## OWL features roadmap\n\n- [x] owl:DatatypeProperty\n- [x] owl:ObjectProperty\n- [x] owl:FunctionalProperty\n- [x] owl:inverseOf\n- [ ] Class expressions (including Restrictions)\n- [ ] owl:unionOf\n- [ ] owl:intersectionOf\n- [ ] owl:complementOf\n- [ ] owl:equivalentClass\n- [ ] owl:equivalentProperty\n- [ ] owl:sameAs\n- [ ] owl:disjointWith\n- [ ] owl:differentFrom\n- [ ] owl:ReflexiveProperty\n- [ ] owl:SymmetricProperty\n- [ ] owl:TransitiveProperty\n- [ ] owl:AsymmetricProperty\n- [ ] owl:IrreflexiveProperty\n- [ ] owl:InverseFunctionalProperty\n\nThe following features will not be implemented due to their incomptability with GraphQL:\n\n- Some items of the preceding list might be impossible to implement and end up here.\n\n## Contributing\n\nYes, thank you. Please lint, update/write tests and add your name to the package.json file before you PR.\n\n## License\n\nSemantic GraphQL is released under the MIT License.\n\nGraphQL is released by Facebook, inc. under the [BSD-license](https://github.com/graphql/graphql-js/blob/master/LICENSE)\nwith an additional\n[patent grant](https://github.com/graphql/graphql-js/blob/master/PATENTS).\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdherault%2Fsemantic-graphql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdherault%2Fsemantic-graphql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdherault%2Fsemantic-graphql/lists"}