DataPower API Gateway
only

Securing a GraphQL API by using a client ID

If you select the Secure using Client ID option when creating a GraphQL proxy API, API Connect automatically adds Rate limit policies to the API assembly.

This section details the Rate limit policy configuration that is generated automatically. If the Secure using Client ID option is not selected at creation time, and you later decide that you want to enable it, you must add the appropriate Rate limit policies manually to the API assembly.

The automatically generated Rate limit policies are added to the switch cases in the assembly as follows:

  • switch case:
    ($operationPath() = '/graphql' and message.attributes.parse.GraphQLIntrospection = 'not-introspection' and message.attributes.graphql.operationType = 'subscription')
    A single Rate limit policy with the following property settings:
    Property Value
    Source Plan by Name
    Count Limit Name graphql-subscription-type-cost
    Operation Increment
    Count Limit Name graphql-subscription-field-cost
    Operation Increment

    The policy as it appears in the assembly UI is as follows:Screen capture showing rate limit policy for first switch case

    This Rate limit policy limits the number of HTML web browser requests for a GraphiQL editor sent to the /graphql endpoint.

  • switch case:
    ($operationPath() = '/graphql' and message.attributes.parse.GraphQLIntrospection = 'not-introspection' and message.attributes.graphql.operationType != 'subscription')

    Two Rate limit policies with the following property settings:

    • Policy 1:
      Property Value
      Source Plan by Name
      Rate Limit Name graphql-type-cost
      Operation Consume
      Rate Limit Name graphql-field-cost
      Operation Consume
      Rate Limit Name graphql-input-type-cost
      Operation Consume

      This Rate limit policy limits calls to the GraphQL proxy API by calculating the expected cost of the query, and then correspondingly reducing the available cost balance that remains of the total configured cost limit. The expected cost is calculating by applying the weighting factors that have been attached to the types and fields in the GraphQL schema; for more information, see Using the GraphQL schema editor.

      The expected cost is calculated by the Validate policy that precedes the Rate limit policy and placed in the API context to be made available to the Rate limit policy. For details on the Validate policy, see Validate.

      The details of the cost calculations to which the referenced rate limits are applied are as follows:

      • graphql-field-cost: The weighted sum of fields being selected in a query. Fields that return values of scalar or enum types have a weight of 0.0 and therefore don't affect field cost.
        For example, consider the following query, where it is assumed that the value max in the filter argument of field Query.offices constrains the number of Office objects being returned:
        query {
          offices (filter: {location: "NY", max: 3}) {
            address {
              street
            }
          }
        }

        The Address.street field is of type String and therefore has a weight of 0.0. Non scalar and non enum field weights that are not changed in the GraphQL schema editor assume a default value of 1.0. If the Office.address field weight has been set to 3.0, the total field cost is 10.0, calculated as follows:

        Field Weight Field cost
        Query.offices 1.0 1 x 1.0 = 1.0
        Office.address 2.0 3 x 3.0 = 9.0
        Address.street 0.0 0.0
          Total cost: 1.0 + 9.0 + 0.0 = 10.0
      • graphql-type-cost:

        The weighted sum of types being returned by a query. Scalar or enum types have a weight of 0.0 and therefore don't affect type cost.

        Considering the previous example, and assuming that all types have a default weight of 1.0, the total type cost is 7 (1 x Query type + 3 x Office types + 3 x Address types.

      • graphql-input-type-cost:

        The weighted sum of input types being sent in a query. Scalar or enum input types have a weight of 0.0 and therefore don't affect input type cost.

        Considering the previous example, the input type cost is 1.0, because one FilterInput type is sent in the filter argument. FilterInput.location is a String type and FilterInput.max is an Int type, so they are not included as they are scalars.

    • Policy 2:
      Property Value
      Source Plan by Name
      Rate Limit Name graphql-type-cost
      Operation Replenish
      Rate Limit Name graphql-field-cost
      Operation Replenish

      This Rate limit policy limits calls to the GraphQL proxy API by calculating the actual cost of the query, and then correspondingly reducing the available cost balance that remains of the total configured cost limit. The actual cost is calculating by applying the weighting factors that have been attached to the types and fields in the GraphQL schema; for more information, see Using the GraphQL schema editor.

      Note that if the actual cost is less than the expected cost, this Rate limit policy will appropriately restore some of the available cost balance that had been removed by Policy 1, thereby overriding the original actual cost limitation. The actual cost might be less than the expected cost if, for example, the query requested more data than was available in a backend database. You can delete one or other of these Rate limit policies from the assembly if desired.
      Note: Such unused cost is not restored if there are GraphQL response errors. The purpose of this restriction is to prevent malicious requests that cause large amounts of erroneous backend processing while only using a small amount of cost.

      The actual cost is calculated by the Validate policy that precedes the Rate limit policy and placed in the API context to be made available to the Rate limit policy. For details on the Validate policy, see Validate.

    The policies as they appear in the assembly UI are as follows:Screen capture showing rate limit policies for second switch case

  • switch case:
    ($operationPath() = '/graphql/cost' and message.attributes.parse.GraphQLIntrospection = 'not-introspection')
    A single Rate limit policy with the following property settings:
    Property Value
    Source Plan by Name
    Rate Limit Name graphql-design-request
    Operation Consume
    The policy as it appears in the assembly UI is as follows:
    Screen capture showing rate limit policy for third switch case

    This Rate limit policy limits the requests sent to the /graphql/cost endpoint for retrieving the cost of a GraphQL query.

  • switch case:
    ($operationPath() = '/graphql' and message.attributes.parse.GraphQLIntrospection = 'standard-introspection')
    A single Rate limit policy with the following property settings:
    Property Value
    Source Plan by Name
    Rate Limit Name graphql-design-request
    Operation Consume
    The policy as it appears in the assembly UI is as follows:
    Screen capture showing rate limit policy for fourth switch case

    This Rate limit policy limits standard introspection requests sent to the /graphql endpoint.

The rate limits that are referred to by the Rate Limit Name settings in these policies are predefined in Plans that are created in Products that contain one or more GraphQL proxy APIs. You can configure the actual rate limiting values there; for more information, see Editing a draft Product.

For more information on the Rate Limit policy, see Rate Limit.