Validation and security
Requests are checked against their operation: path, query, header and cookie parameters in every
style, and JSON, XML, form and multipart bodies. A request that doesn’t match is answered with 422
and the problems, a body that can’t be parsed (JSON, XML, multipart) with 400, an unknown media type
with 415. Security
requirements are checked for presence (API keys, HTTP basic and bearer, OAuth2 and OpenID Connect
tokens; 401 with WWW-Authenticate), and against configured credentials in enforce mode (403).
Responses the mock makes are checked too: problems are logged and counted in
X-Apigenie-Mock-Violations, or answered with 500 under --strict.
Schemas’ format values are checked as the
OpenAPI format registry defines them, for the JSON types each
format applies to (int8 ranges, http-date, decimal, language, …);
validation.formats: false turns these checks off. Formats of your own, declared in
openapi.custom_formats of the
configuration file, are accepted as they are, and an entry there naming a registry format
replaces that format’s type and its check.
XML bodies
Bodies of application/xml, text/xml and +xml media types are parsed as XML 1.0 with
namespaces, mapped to a JSON value as the schema’s xml objects describe it, and checked against
the schema like JSON bodies; the mock, the validating proxy and apigenie test do the same, and
the mock and apigenie test --generate write XML the same way in reverse. For this schema
Order:
type: object
xml: {name: order, namespace: "urn:orders", prefix: o}
properties:
id: {type: integer, xml: {nodeType: attribute}} # OpenAPI 3.0/3.1: attribute: true
customer: {$ref: "#/components/schemas/Customer"} # Customer has xml: {name: Buyer}
note: {type: string, xml: {nodeType: cdata}}
tags: {type: array, items: {type: string, xml: {name: tag}}}
lines:
type: array
xml: {name: Lines, nodeType: element} # 3.0/3.1: wrapped: true
items: {$ref: "#/components/schemas/Line"} # Line has xml: {name: Line}
the body is
<o:order xmlns:o="urn:orders" id="7">
<Buyer><name>Ann</name></Buyer>
<![CDATA[Leave at the <door>]]>
<tag>a</tag><tag>b</tag>
<Lines><Line sku="x"><quantity>2</quantity></Line></Lines>
</o:order>
- The root element is named by the schema’s
xml.name, else by the component a$refpoints to; another name is axml-rootviolation. A schema without either names no root. - A property is a child element named by its
xml.name(its own, or that of the schema it references), else by the property name.nodeType: attributemakes it an attribute,textandcdatathe element’s character data. - An array’s items repeat in the parent element, named by the items’
xml.nameor the property name; withnodeType: element(wrapped: true) they sit in a wrapper element. - A declared
xml.namespacemust match; without one, elements are matched by local name in any namespace. An element with a property’s local name in another namespace isn’t that property: it is kept as{namespace}name, so the property is missing andadditionalProperties: falsereports the element. - Child elements are written in the order the schema declares its properties, as XML Schema sequences require.
- Text becomes an integer, number, boolean or null where the schema allows it (white space around
such values is ignored);
xsi:nil="true"is null. Elements and attributes the schema doesn’t declare are kept by local name, soadditionalProperties: falsereports them. - A body that isn’t well-formed is
malformed-xml(request.body.malformed, answered with 400;response.body.malformed), with its line and column. Document type declarations are refused, so external entities and entity expansion are errors.
A SOAP service described in WSDL 1.1 is served after
apigenie convert --to openapi31: the converted
document describes the SOAP envelopes with these xml objects.