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 criteria
  • orderBy: a filter object that defines the result ordering (for example, orderBy: {field: LICENSE, direction: ASC} will sort according to the LICENSE field in ascending order)
📘

Note

The where and orderBy arguments 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 page
  • after: 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 page
  • before: 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 first and last depend on each query.
  • after is 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/before is provided, the first page is returned in its default size.
  • first/after and last/before are 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.