effectiveactivism/schema-api

A GraphQL representation of the https://schema.org classes.

Installs: 275

Dependents: 1

Suggesters: 0

Security: 0

Stars: 0

Forks: 0

Type:symfony-bundle

7.4.0 2022-09-10 10:59 UTC

README

DEPRECATED: Use https://gitlab.com/effective-activism/schema-org-api instead.

~GraphQL representation of the https://schema.org classes.~

Table of content

Installation

Run composer require effectiveactivism/schema-api.

Configuration

If your vocabulary extends the schema.org specification with custom namespaces, you need to add them to the configuration of this bundle. This ensures that the bundle can correctly parse terms using your custom namespaces.

schema_api:
  namespaces:
    - my_custom_vocabulary: http://example.com/

Blazegraph supports an internal full-text search engine that can optionally be utilized. To enable it, use the following configuration:

schema_api:
  ...
  use_bds_service: true

For more information, see Full-text search.

Usage

Every schema.org class is represented as multiple GraphQl fields.

For example, the class https://schema.org/WebPage has the fields getWebPage, getWebPages, insertWebPage, updateWebPage and deleteWebPage.

Input arguments

  • To retrieve data (using a get... field), one or more filters must be specified.

    query { getWebPage ( filters: { ... }) { ... }
    
    query { getWebPages ( filters: { ... }) { ... }
    
  • To insert data (using an insert... field), one or more values must be specified.

query { insertWebPage ( values: { ... }) { ... }
  • To update data (using an update... field), both filters and values must be specified.
query { updateWebPage ( filters: { ... } values: { ... }) { ... }
  • To delete data (using a delete... field), one or more filters must be specified.
query { deleteWebPage ( filters: { ... }) { ... }

Filters

Any schema.org property takes multiple types of filters.

Most filters are text, which can be written like so:

query { getWebPage ( filters: { identifier: { equalTo: "..." }}) { ... }

If another type is needed, it is possible to define it using the type field:

query { getEvent ( filters: { maximumAttendeeCapacity: { equalTo: "10" type: "IntegerBox" }}) { ... }

The format of filters (and data values) is used because the GraphQL specification doesn't support union types as input arguments.
Therefore, this API introduces an abstraction to handle multiple types per property.

Filter types available:

  • equalTo
  • greaterThan
  • greaterThanOrEqualTo
  • lessThan
  • lessThanOrEqualTo
  • notEqualTo
  • searchFor (if full-text search is enabled)

For example:

query { getEvent ( filters: { startDate: { greaterThan: "2020-01-01T10:00:00Z" type: "DateTimeBox" }}) { ... }

Data types

All schema.org DataTypes, like schema.org/Text or schema.org/Boolean, have a Box suffix. This ensures that it does not collide with GraphQL built-in types (such as Boolean and Float).

query { getPerson ( filters: { alternateName: { equalTo: "..." type: "TextBox" }}) { ... }

Note that schema.org/Float is not used by any schema.org classes at the time of writing. Instead schema.org/Number is used for decimal values. When querying for a decimal value, NumberBox should always be used in favor of FloatBox.

Multiple values

To filter by more than one value for the same property, or insert/update multiple values for the same property, simply use an array.

query { updateWebPage ( filters: { identifier: { equalTo: "..." }} values: { headline: [{ value: "foo" }, { value: "bar" }]}) { headline { ... on TextBox { value }}}}

Query

To get the schema.org/headline of a schema.org/WebPage, the following query can be used:

query { getWebPage (data: { identifier: { value: "..." }}) { headline { ... on TextBox { value }}}}

which will return

{"data":{"WebPage":{"headline":[{"value":"foo"}]}}}

Any schema.org/DataType, such as Text, Boolean or DateTime, will have a Box suffix to ensure that it doesn't conflict with GraphQL built-in types ( such as Boolean and Float).

Multiple result query

All schema.org classes have been pluralized to support multiple result queries.

To get multiple results of schema.org/WebPage, the following query can be used:

query { getWebPages (filters: { creditText: { equalTo: "..." }}) { headline { ... on TextBox { value }}}}

which will return

{"data":[{"WebPage":{"headline":[{"values":"foo"}]}},{"WebPage":{"headline":[{"values":"bar"}]}}]}

Ordering results

To order multiple results, use orderBy: {"..."} and a field name to order by.

Results are ordered in ascending order by default. The direction can be switched by using orderAscending: false.

Full-text search

If the configuration option use_bds_service is set to true, an extra type of filter is available to use full-text search on filter values of type TextBox.

For example, the query

query { getWebPages (filters: { creditText: [{ searchFor: "foo" }, { searchFor: "bar" }]}) { headline { ... on TextBox { value }}}}

will return matches with creditText containing "foo" or "bar" (or both).

Additionally, the query

query { getWebPages (filters: { headline: { searchFor: "Lorem" } creditText: [{ searchFor: "foo" }, { searchFor: "bar" }]}) { headline { ... on TextBox { value }}}}

will return matches with headline containing "Lorem" and creditText containing either "foo" or "bar" (or both).

Mutation

Insert

To create new content, use the insert... field. This will create new content using the class and any input arguments provided. If an identifier has been set as value, it will be overwritten.

mutation { insertWebPage (values: { headline: { value: "foo" }}) { identifier { ... on TextBox { value }}}}

Update

To alter existing content, use the update... field. Use the filter argument to select the content to update and the values argument to change content. If an identifier has been set as value, it will be omitted.

mutation { updateWebPage (filters: { identifier: { equalTo: "..." }} values: { headline: { value: "foo" }}) { headline { ... on TextBox { value }}}}

The default 'update' operation is to add additional values to existing values.

To instead overwrite existing values with new values, use the overwrite: true flag, like this:

mutation { updateWebPage (overwrite: true filters: { identifier: { equalTo: "..." }} values: { headline: { value: "foo" }}) { headline { ... on TextBox { value }}}}

Delete

To delete content, use the delete... field and specify what content to delete with the filter argument.

mutation { deleteWebPage (filters: { identifier: { equalTo: "..." }}}

The default 'delete' operation is to remove any related values.

To instead delete only some values, use the onlyDelete filter, like this:

mutation { deleteWebPage ( onlyDelete: { headline { value: "..." }} filters: { identifier: { equalTo: "..." }}}

Roles

All schema.org properties have the https://schema.org/Role class as a type. This allows for additional information about a relationship between a subject and a predicate.

For example, to describe that Bill Murray was an actor in the movie Ghost Busters, the following triple can be used:

@prefix schema: <https://schema.org/> .

<urn:uuid:...> schema:actor "Bill Murray" .

However, to describe that Bill Murray played the role of Dr. Peter Venkman in that movie, a Role can be used:

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix schema: <https://schema.org/> .

<urn:uuid:...> schema:actor <urn:uuid:foo> .
<urn:uuid:foo> rdf:type <schema:Role> .
<urn:uuid:foo> rdf:roleName "Dr. Peter Venkman" .
<urn:uuid:foo> rdf:actor "Bill Murray" .

This can be expressed using the Schema API as such:

query { getMovie ( filters: { identifier: { equalTo: "..." }}) { actor { ... on ActorRole { roleName { ... on TextBox { value }} actor { ... on TextBox { value }}}}}}

which will return

{"data":{"Movie":{"actor":[{"roleName":[{"value":"Dr. Peter Venkman"}],"actor":[{"value":"Bill Murray"}]}]}}}

>Note that in the Schema.org API, all schema.org properties, such as actor, have corresponding Role types, such as ActorRole. These Role types do not exist in the schema.org vocabulary, but are a necessity to allow the many variations of Role types to be strongly typed, which GraphQL requires.

If a Role class has an incoming property that conflicts with existing fields defined by the Role class, the incoming property will be prefixed with an underscore (_).

For example, the property endDate uses the EndDateRole as such:

query { getEvent (filters: { identifier: { equalTo: "..." }}) { endDate { ... on EndDateRole { _endDate { ... on DateBox { value }}}}}

Validation

If a SHACL endpoint has been defined in the SparQl client, it is possible to validate insert, update and delete statements.

To enable it, add a service that implements the ValidationInterface found in src/Validation.

An ExampleValidation class is also included to demonstrate a simple implementation of the validate() method.

To use the example validation, add the following to your services.yaml file:

  EffectiveActivism\SchemaApi\Validation\ExampleValidation:
    class: EffectiveActivism\SchemaApi\Validation\ExampleValidation
    tags: ['schema_api.validation']

For more information on setting up a SHACL endpoint, see the Readme file of the SparQl client.

Security

This bundle is configured for Symfony security voters. An abstract basic voter is included in the src/Security folder, which you can extend for your own purposes.

An ExampleSchemaApiVoter class is also included to demonstrate a simple implementation of the voteOnAttribute() method.

To use the example voter, add the following to your services.yaml file:

  EffectiveActivism\SchemaApi\Security\ExampleSchemaApiVoter:
    class: EffectiveActivism\SchemaApi\Security\ExampleSchemaApiVoter
    tags: ['security.voter']

To use your own security voter, follow the Symfony instructions here .

Planned features

  • Use built-in roles when available, such as schema:OrganizationRole instead of schema:Role.