Skip to main content

GraphQL API

Turing ES exposes a GraphQL endpoint that provides the same Semantic Navigation search capabilities as the REST API but using GraphQL queries. The endpoint is public — no authentication required.

POST http://localhost:2700/graphql

GraphiQL Explorer

An interactive GraphQL IDE is available in the admin console and at /graphiql. It provides:

  • Schema introspection — browse all types, queries, and fields
  • Auto-completion — press Ctrl+Space for field suggestions
  • Query validation — syntax and type errors are highlighted in real time
  • Query history — previously executed queries are saved locally

The explorer synchronizes its theme (light/dark) with the Turing ES console.


Queries

siteNames

Returns all configured Semantic Navigation site names as a string array, sorted alphabetically.

query {
siteNames
}

Response:

{
"data": {
"siteNames": ["Customer Portal", "Knowledge Base", "Sample"]
}
}

siteSearch

Performs a search against a Semantic Navigation site. This is the primary query — it mirrors the full capability of the REST search endpoint.

query {
siteSearch(
siteName: TurSNSiteName!
searchParams: SearchParamsInput!
locale: String!
): SiteSearchResult
}
ArgumentTypeDescription
siteNameTurSNSiteName!Site name as a dynamic enum value (see Site Name Enum)
searchParamsSearchParamsInput!Search parameters (see SearchParamsInput)
localeString!Locale code (e.g., en_US, pt_BR). Falls back to en if not supported by the site.

Site Name Enum

Site names are exposed as a dynamic GraphQL enum (TurSNSiteName) that is generated at runtime from the configured sites in the database.

Conversion rules:

Site NameEnum ValueRule Applied
SampleSAMPLEUppercase
My Sample SiteMY_SAMPLE_SITESpaces → underscores
Site 2.0!SITE_2_0_Special characters → underscores
123 NumbersSITE_123_NUMBERSNumeric prefix → SITE_ prepended
__internalSITE___INTERNALDouble underscore prefix → SITE_ prepended

Duplicate handling: If two sites produce the same enum value, the second one gets a _2 suffix, the third _3, and so on.

The enum always includes UNKNOWN as the first value. Use the siteNames query to discover available site names, then convert to the enum format for siteSearch.


SearchParamsInput

FieldTypeDefaultDescription
qString*Search query text
rowsIntSite defaultResults per page (use -1 for site default)
pInt1Page number
sortStringrelevanceSort field and direction (e.g., relevance, date desc)
groupStringGroup results by a field value
nfprInt1Number of facets per row in grouped results
fq[String]Filter queries (e.g., ["type:article"])
fqAnd[String]AND filter queries
fqOr[String]OR filter queries
fqOpStringNONEFilter operator between facets: AND, OR, or NONE
fqiOpStringNONEFilter operator within facet values: AND, OR, or NONE
localeStringOverride locale (takes precedence over the top-level locale argument)
fl[String]Field list — restrict which document fields are returned

Filter Operators

The fqOp and fqiOp parameters control how multiple filter queries are combined:

ValueBehaviorExample
NONENo filter logic appliedDefault — filters are passed as-is
ANDAll filters must matchfq: ["type:article", "dept:HR"] with fqOp: "AND" → documents must be type:article AND dept:HR
ORAny filter may matchfqOr: ["type:article", "type:news"] with fqOp: "OR" → documents matching either type

Invalid operator values fall back to NONE.


Response Schema

SiteSearchResult

The top-level response object:

FieldTypeDescription
pagination[SearchPagination]Pre-built page links
queryContextSearchQueryContextResult metadata and statistics
resultsSearchResultsDocument list with facets
groups[SearchGroup]Grouped results (when group parameter is used)
widgetSearchWidgetWidget HTML content

SearchQueryContext

FieldTypeDescription
countIntTotal number of matching documents
indexStringSite name
limitIntResults per page
offsetIntResult offset
pageIntCurrent page number
pageCountIntTotal number of pages
pageEndIntLast result index on this page
pageStartIntFirst result index on this page
responseTimeIntQuery execution time in milliseconds
querySearchQueryOriginal query parameters (q, sort, p, rows, group, nfpr)
defaultFieldsSearchDefaultFieldsDefault field mappings (title, text, url, date, description, image)
facetTypeStringFacet operator type
facetItemTypeStringFacet item operator type

SearchResults

FieldTypeDescription
numFoundIntTotal matching documents
startIntResult offset
document[SearchDocument]Array of matching documents
facet[SearchFacet]Facet groups with counts

SearchDocument

FieldTypeDescription
sourceStringSource system (e.g., TURING)
fieldsSearchDocumentFieldsDocument field values (see Document Fields)
metadata[SearchDocumentMetadata]Key-value metadata pairs with name and value

SearchFacet

FieldTypeDescription
nameStringFacet field name
label[SearchFacetLabel]Localized labels (lang, text)
facets[SearchFacetItem]Individual facet values

SearchFacetItem

FieldTypeDescription
labelStringFacet value label
countIntNumber of documents with this value
linkStringPre-built filter link

SearchPagination

FieldTypeDescription
textStringDisplay text (e.g., "1", "Next")
hrefStringPre-built page link
pageIntPage number
currentBooleanWhether this is the current page

SearchGroup

FieldTypeDescription
nameStringGroup value (e.g., category name)
countIntNumber of documents in this group
pageIntCurrent page within the group
pageCountIntTotal pages in the group
pageEndIntLast result index
pageStartIntFirst result index
limitIntResults per page
resultsSearchResultsDocuments within this group
pagination[SearchPagination]Pagination for this group

SearchWidget

FieldTypeDescription
idStringWidget identifier
nameStringWidget name
descriptionStringWidget description
htmlStringRendered HTML content

Document Fields

Static Fields

Every document exposes these standard fields in SearchDocumentFields:

FieldTypeDescription
idStringDocument unique identifier
titleStringDocument title
textStringFull text content
urlStringDocument URL
dateStringPublication or modification date
descriptionStringShort description or summary
imageStringImage URL

Dynamic Fields

The GraphQL schema is dynamically extended at runtime with custom fields from your SN Site configuration. If your site defines fields like category, author, or department, they appear as additional fields on SearchDocumentFields with the JSON scalar type.

How it works:

  1. At startup, Turing reads all field extensions from every configured SN Site
  2. Fields with valid GraphQL names (matching ^[_A-Za-z]\w*$, no __ prefix) are collected
  3. Static fields (id, title, text, url, date, description, image) are excluded to avoid conflicts
  4. The schema is extended: extend type SearchDocumentFields { category: JSON, author: JSON, ... }

Dynamic fields use the JSON scalar type, which can hold strings, numbers, arrays, or nested objects — matching the flexible nature of indexed document attributes.

Field list projection

Use the fl parameter in SearchParamsInput to restrict which fields are returned. This reduces response size and can improve performance when you only need specific fields.

searchParams: { q: "report", fl: ["title", "url", "category"] }

Locale Resolution

The locale for a search is resolved with the following precedence:

  1. searchParams.locale — if provided in the input, takes highest priority
  2. Top-level locale argument — the required locale parameter on siteSearch
  3. Default — falls back to en if neither is provided or the locale is not supported by the site

If the resolved locale is not configured on the target SN Site, the search falls back to the site's first available locale.


Examples

query BasicSearch {
siteSearch(
siteName: SAMPLE
searchParams: {
q: "technology"
rows: 10
p: 1
sort: "relevance"
}
locale: "en"
) {
queryContext {
count
page
pageCount
responseTime
}
results {
numFound
start
document {
fields { title, text, url, date }
source
}
}
pagination { text, href, page, current }
}
}

Advanced Search with Filters and Facets

query AdvancedSearch {
siteSearch(
siteName: SAMPLE
searchParams: {
q: "annual report"
rows: 10
p: 1
fq: ["type:article", "department:Finance"]
fqOp: "AND"
fl: ["title", "url", "date"]
}
locale: "en_US"
) {
queryContext { count, responseTime }
results {
numFound
document {
fields { title, url, date }
metadata { name, value }
}
facet {
name
label { lang, text }
facets { label, count, link }
}
}
}
}
query GroupedSearch {
siteSearch(
siteName: SAMPLE
searchParams: {
q: "*"
group: "category"
rows: 5
}
locale: "en_US"
) {
groups {
name
count
page
pageCount
results {
document {
fields { title, url }
}
}
pagination { text, page, current }
}
}
}

Search with OR Filters

query OrFilterSearch {
siteSearch(
siteName: SAMPLE
searchParams: {
q: "benefits"
fqOr: ["type:article", "type:news"]
fqOp: "OR"
}
locale: "en_US"
) {
queryContext { count }
results {
document {
fields { title, url }
}
}
}
}
query SimpleSearch {
siteSearch(
siteName: SAMPLE
searchParams: { q: "search" }
locale: "en"
) {
results {
document {
fields { title, url }
}
}
}
}

cURL Example

curl -X POST "http://localhost:2700/graphql" \
-H "Content-Type: application/json" \
-d '{
"query": "query { siteSearch(siteName: SAMPLE, searchParams: { q: \"enterprise search\", rows: 10 }, locale: \"en_US\") { queryContext { count } results { document { fields { title url } } } } }"
}'

Configuration

GraphQL is configured in application.yaml:

spring:
graphql:
graphiql:
enabled: true
path: /graphiql
http.path: /graphql
cors:
allowed-origins: ${turing.allowedOrigins}
allowed-methods: GET,POST
allowed-headers: "*"
PropertyDefaultDescription
spring.graphql.http.path/graphqlGraphQL endpoint path
spring.graphql.graphiql.enabledtrueEnable GraphiQL browser IDE
spring.graphql.graphiql.path/graphiqlGraphiQL IDE path
spring.graphql.cors.allowed-origins${turing.allowedOrigins}CORS allowed origins
spring.graphql.cors.allowed-methodsGET,POSTAllowed HTTP methods

For the full configuration reference, see Configuration Reference → GraphQL.


Error Handling

ScenarioBehavior
Invalid site nameReturns null for siteSearch — the site is not found
Unsupported localeFalls back to the site's first available locale
Invalid filter operatorFalls back to NONE
Invalid field in flField is ignored — only valid fields are returned
Empty query (q: "")Treated as q: "*" (match all)

GraphQL validation errors (missing required fields, wrong types) are returned as standard GraphQL error responses before the query reaches the resolver.


PageDescription
REST API ReferenceREST search endpoint with the same capabilities
Semantic NavigationSN Site configuration — fields, facets, and search behavior
Configuration ReferenceFull application.yaml property reference