JFrog OneModel GraphQL
Starting from Artifactory version 7.104.1, you can use JFrog OneModel GraphQL queries to get information from multiple JFrog products and services through a single endpoint. OneModel aligns domain models and terminology across the JFrog Platform, allowing a unified entry point to query cross-platform information. Additionally, GraphQL queries enable you to query only the data you need, and remove unnecessary fields.
For example, to get information about Release Bundles and evidence associated with them using OneModel, you can use a single query and receive connected information about release bundles and their respective evidence data, instead of using two separate queries and matching the information using regular REST API queries.
The following domains are currently supported in the JFrog OneModel GraphQL:
- Evidence
- Release Lifecycle Management
- Metadata
OneModel GraphQL Authentication
Using OneModel GraphQL requires a JFrog access bearer token, scoped to the content you are querying. For more information about token scopes, see Create Scoped Token.
Note
When using OneModel GraphQL, make sure your token audience is configured as wildcard ( @). For more information, see Create Token.
OneModel GraphQL will only return data that you have permission to view: if you do not have the appropriate permissions for the data, OneModel GraphQL will return an error. For example, to query evidence information for one project in your instance, you will need read permissions for evidence on this project.
Use OneModel GraphQL
Using OneModel, you can access all supported domains using the following unified endpoint:
POST <your-jfrog-domain>/onemodel/api/v1/graphql
Note
JFrog OneModel GraphQL currently supports the POST with JSON format. For more information, see the GraphQL documentation for Request Format and Response Format.
To use the OneModel endpoint, execute your query using curl or an API client application such as Postman. Some simple examples are shown below.
Usage Examples
Query Example
Use the following query to get the first 5 evidences from the repository,example-repo-local:
query {
evidence {
searchEvidence(first: 5, where: {
hasSubjectWith: {
repositoryKey: "example-repo-local",
path: "path/to",
name: "file.ext"}}) {
edges {
node {
predicateSlug
predicateType
predicate
verified
downloadPath
subject {
path
name
}
}
}
}
}
}
cURL Example
Use the following cURL command to execute a query:
curl --location -X POST -H "Content-Type: application/json" -H "Authorization: Bearer <token>" https://johnf.jfrog.io/onemodel/api/v1/graphql -d '{"query":"query { evidence { searchEvidence( first: 5, where: { hasSubjectWith: { repositoryKey: \"example-repo-local\" } } ) { totalCount } } }"}'Best Practices
We recommend the following best practices when using GraphQL:
Use Pagination for Large Result Sets
Always specify first and use the after cursor for subsequent pages to handle large result sets efficiently. For more information about pagination, see One Model GraphQL Common Patterns and Conventions.
Focus Requests on the Fields You Require
The power of GraphQL is the ability to define exactly what information you want returned for each request. Request only the fields you need to minimize response size and improve query performance.
Use Filters to Narrow Results
Apply filtering criteria (for example, 'where' arguments) directly in the query instead of fetching large datasets and filtering them in the application layer.
Use Variables for Dynamic Queries
Define variables for dynamic values to make queries cleaner and reusable, as shown in the following example:
query GetEvidence($repoKey: String!, $path: String!, $name: String!) {
evidence {
getEvidence(
repositoryKey: $repoKey
path: $path
name: $name
) {
id
verified
}
}
}
One Model GraphQL Common Patterns and Conventions
This section includes patterns and conventions that are applied across all One Model domains:
Namespaces and Queries
Each domain in the JFrog Platform model is mapped to a namespace, which is represented by a field in the GraphQL root query. The namespace field itself contains the actual queries.
Queries are named according to the following convention:
search...for queries that return a list of items (the list can be empty)get...for queries that return a single item (the item can be null)
For example, the following query returns a list of evidence items in a specific repository:
query {
# Namespace for Evidence business-domain
evidence {
# Query to search for evidence items in a specific repository
searchEvidence(where: {hasSubjectWith: {repositoryKey: "example-repo-local"}}) {
# Field(s) to include in the result set
totalCount
}
}
}
Search queries usually accept the following arguments to filter and order the results:
where: a filter object that contains the filtering criteriaorderBy: a filter object that defines the result ordering (for example,orderBy: {field: LICENSE, direction: ASC}will sort according to theLICENSEfield in ascending order)
Note
The
whereandorderByarguments are not supported for all queries: check the specific query before using these arguments.
Pagination
Some search queries provide paginated results to allow the handling of very large result sets. In these cases, pagination is cursor-based and implemented according to the widely-adopted Relay style.
For example, the following query returns a paginated list of evidence items:
query {
evidence {
searchEvidence(where: {hasSubjectWith: {repositoryKey: "example-repo-local"}}) {
# Items of the current page
edges {
node {
# Evidence fields for the current item
name
verified
}
# Cursor value for the current item
cursor
}
# Information about the current page
pageInfo {
# Whether there are more items in the next page
hasNextPage
# Cursor value for the last item in the current page
endCursor
}
}
}
}
To iterate over pages, use the following query arguments:
first: the number of items to include in the pageafter: the cursor value of the item after which to fetch the page, which is usually the last item in the previous page.
Paginated queries may also support backward pagination, which is implemented in the same way as forward pagination but with the following arguments:
last: the number of items to include in the pagebefore: the cursor value of the first item in the next page
Note
Note the following guidelines for using pagination:
- The default values for pagination query arguments
firstandlastdepend on each query.afteris optional: in forward pagination, if not provided, the first page is fetched. The same logic applies for backwards pagination, where last is optional.- If none of
first/last/after/beforeis provided, the first page is returned in its default size.first/afterandlast/beforeare mutually exclusive and cannot be used in the same query.
Field Values
Date Values
Fields ending with ...At (for example, createdAt) are used to represent timestamp values (date and time).
By default, timestamps are shown using the ISO-8601 format in UTC timezone (marked by the Z suffix), for instance:
2024-11-05T13:15:30.972Z.
You may select a different date format with the @dateFormat directive:
@dateFormat(format: ISO8601_DATE_ONLY): same as the default format, but hiding the time part (for example, 2024-11-05)@dateFormat(format: DD_MMM_YYYY): date-only in a "long" format (e.g. 05 Nov 2024)
For example:
query {
evidence {
searchEvidence() {
edges {
node {
createdAt @dateFormat(format: DD_MMM_YYYY)
}
}
}
}
}
Username Values
Fields ending with ...By (for example, createdBy) are used to represent the user who performed an action.
Experimental Features and Deprecation
Experimental features are marked with the @experimental directive. These are new features and may be subject to breaking changes in future releases. Pay attention to this directive, meaning you use these features at your own risk.
Deprecations are marked with the @deprecated directive. Deprecated features are still available, but will be removed in future releases. Pay attention to this directive, and change your queries according to the deprecation notice.
Updated 1 day ago
