GraphQLRequestValidation#
Действие GraphQLRequestValidation предназначено для валидации запроса GraphqQL.
На текущий момент реализованы:
Парсинг graphql запроса из тела (json|graphql в зависимости от content-type) и параметров url запроса;
Валидация по схеме;
Запрет introspection query (включен всегда);
Возможность ограничения запроса по глубине.
Парсинг запроса происходит согласно рекомендации Serving over HTTP (оригинал на graphql.org) если следовать примеру ниже.
GraphQL запрос состоит из 3 частей:
query - запрос(ы);
operationName - наименование операции из query, которая запрашивается клиентом;
variables - список значений переменных, использующихся в query.
Поддерживаемые варианты передачи данных параметров:
В параметрах url.
Используется для get запросов.
http://host:port/graphql?query=...&variables=...&operationName=...В теле запроса в JSON обертке.
Используется для POST запросов.
http://host:port/graphql { "query": "...", "operationName": "...", "variables": { "myVariable": "someValue", ... } }В теле запроса в JSON обертке, при этом query - в параметрах url.
Используется для POST запросов.
http://host:port/graphql?query=... { "operationName": "...", "variables": { "myVariable": "someValue", ... } }В теле запроса только query без json обертки.
Используется для POST запросов, когда не требуется передавать ни operationName, ни variables.
Для того чтобы обеспечить возможность настройки парсинга, введены следующие параметры:
Название |
Обязательность |
Допустимые значения |
Описание |
|---|---|---|---|
input_is_url_params |
- |
true/false |
Необязательный параметр, сигнализирующий о том, что message - urlencoded строка. Используется для GET запросов, когда на вход цепочке идут аргументы запроса из url. Значение по умолчанию: false. |
query_can_be_in_url |
- |
true/false |
Необязательный параметр, сигнализирующий о том, что необходимо парсить не только message, но также аргументы запроса из url. Используется для POST запросов, когда на вход цепочке идет тело сообщение, но также в параметрах url может быть query. Значение по умолчанию: false. |
При этом наличие/отсутствие json обертки определяется по заголовку сontent-type.
По умолчанию параметры query, variables, operationName берутся из одноименных полей.
В случае, если названия полей отличаются, можно использовать следующие параметры парсинга:
Название |
Обязательность |
Допустимые значения |
Описание |
|---|---|---|---|
queryField |
- |
строка |
Название поля с query. Значение по умолчанию: query |
operationNameField |
- |
строка |
Название поля с operationName. Значение по умолчанию: operationName |
variablesField |
- |
строка |
Название поля с variables. Значение по умолчанию: variables |
Параметры валидации:
Название |
Обязательность |
Допустимые значения |
Описание |
|---|---|---|---|
validation_schema |
+ |
Элемент вида {type: file, path: путь} |
Обязательный параметр, определяющий относительный путь к схеме валидации от каталога ресурсов профиля, задается в виде: {type: file, path: путь_к_схеме}. |
extended_scalars |
- |
Элемент вида {type: file, path: путь} |
Необязательный параметр, определяющий относительный путь к yml файлу описания расширенных скаляров от каталога ресурсов профиля. |
max_query_depth |
- |
Положительное число |
Необязательный параметр. В случае, если необходима проверка на максимальную глубину запроса, необходимо задать этот параметр. |
max_query_amount |
- |
Положительное число |
Необязательный параметр. В случае, если необходима проверка на максимальную ширину запроса, необходимо задать этот параметр. |
Рассмотрим пример:
chains:
request_chains:
- message: $clj_request_body
actions:
- action: GraphQLRequestValidation
params:
validation_schema: { type: file, path: schemes/graphql_max_depth/small_schema_with_mutation.graphqls }
extended_scalars: { type: file, path: schemes/extended_scalars.yml }
max_query_amount: 1
max_query_depth: 4 validation_schema: {type: file, path: schemes/small_schema.graphqls}
conditions:
- {var: $clj_request_body, operator: "!=", val: ""}
- message: $args
actions:
- action: GraphQLRequestValidation
conditions:
- {var: $clj_request_body, operator: "=", val: ""}
params:
validation_schema: { type: file, path: schemes/graphql_max_depth/small_schema_with_mutation.graphqls }
extended_scalars: { type: file, path: schemes/extended_scalars.yml }
input_is_url_params: true
max_query_amount: 1
max_query_depth: 4
В приведенном примере валидация осуществляется в зависимости от наличия тела запроса.
В случае непустого тела запроса (актуально для POST/PUT):
задается параметр
validation_schema - путь к схеме валидации;
по умолчанию параметры
input_is_url_params = false
query_can_be_in_url = true.
Этот случай покрывает варианты парсинга 2,3,4.
В случае пустого тела запроса (актуально для GET):
задаются параметры
validation_schema - путь к схеме валидации;
input_is_url_params = true.
Этот случай покрывает вариант парсинга 1.
Рассмотрим подробнее вопрос описания расширенных скаляров:
По умолчанию graphql поддерживает 5 базовых типов: String, Int, Float, Boolean, ID (basic-types).
Также были добавлены скаляры, описанные в библиотеке graphql-java-extended-scalars (полный список case sensitive:Locale, Object, JSON, Time, Date, DateTime, Url, Char, Byte, Long, Short, BigDecimal, PositiveInt, NonPositiveFloat, BigInteger, NegativeFloat, PositiveFloat, NonNegativeFloat, NonNegativeInt, NonPositiveInt, NegativeInt, Currency, CountryCode, UUID, LocalTime).
В случае, если необходимо добавить собственное наименование для стандартного типа, или же задать Regex для строкового типа, можно задать файл с описанием расширенных скаляров, например:
- name: Map
base_scalar: JSON
- name: LocalDate
base_scalar: Regex
pattern: ^\d{4}-\d{2}-\d{2}$
- name: LocalDateTime
base_scalar: Regex
pattern: \d{4}-[01]\d-[0-3]\d\s[0-2]\d((:[0-5]\d)?){2}
В случае с новым именем для скаляра, необходимо в поле name указать имя нового скаляра, в base_scalar - имя базового скаляра.
В случае с заданием регулярного выражения для строкового типа необходимо в поле name указать имя нового скаляра, в base_scalar - Regex, в pattern - регулярное выражение.