# Spectral ruleset for the Spoonacular Recipe and Food API # Generated by the API Evangelist pipeline from the official Spoonacular OpenAPI 3 spec # (ddsky/spoonacular-api-clients). Enforces the conventions observed across the spec: # - camelCase paths and operationIds # - Title Case tags # - API key auth via the x-api-key header # - offset / number pagination extends: [[spectral:oas, off]] rules: # --------------------------------------------------------------- # INFO / METADATA # --------------------------------------------------------------- info-title-prefix: description: API title should reference spoonacular. severity: warn given: $.info then: field: title function: pattern functionOptions: match: "(?i)spoonacular" info-description-required: description: Info object must have a non-empty description. severity: warn given: $.info then: field: description function: truthy info-version-required: description: Info object must declare a version. severity: error given: $.info then: field: version function: truthy # --------------------------------------------------------------- # OPENAPI VERSION # --------------------------------------------------------------- openapi-version-3: description: Spec must be OpenAPI 3.x. severity: error given: $ then: field: openapi function: pattern functionOptions: match: "^3\\." # --------------------------------------------------------------- # SERVERS # --------------------------------------------------------------- servers-defined: description: A servers array must be defined. severity: error given: $ then: field: servers function: truthy servers-https: description: Server URLs must use HTTPS. severity: error given: $.servers[*] then: field: url function: pattern functionOptions: match: "^https://" # --------------------------------------------------------------- # PATHS — NAMING CONVENTIONS # --------------------------------------------------------------- paths-no-trailing-slash: description: Paths should not end with a trailing slash. severity: warn given: $.paths[*]~ then: function: pattern functionOptions: notMatch: ".+/$" paths-camel-case: description: Path segments use camelCase (Spoonacular convention, e.g. /recipes/complexSearch). severity: info given: $.paths[*]~ then: function: pattern functionOptions: match: "^(/[a-zA-Z0-9{}\\-]+)+$" # --------------------------------------------------------------- # OPERATIONS # --------------------------------------------------------------- operation-summary-required: description: Every operation must have a summary. severity: warn given: $.paths[*][get,post,put,delete,patch] then: field: summary function: truthy operation-description-required: description: Every operation must have a description. severity: warn given: $.paths[*][get,post,put,delete,patch] then: field: description function: truthy operation-operationid-required: description: Every operation must have an operationId. severity: error given: $.paths[*][get,post,put,delete,patch] then: field: operationId function: truthy operation-operationid-camel-case: description: operationId should be camelCase (e.g. searchRecipes, getRecipeInformation). severity: warn given: $.paths[*][get,post,put,delete,patch].operationId then: function: pattern functionOptions: match: "^[a-z][a-zA-Z0-9]*$" operation-tags-required: description: Every operation must be tagged. severity: warn given: $.paths[*][get,post,put,delete,patch] then: field: tags function: truthy # --------------------------------------------------------------- # TAGS # --------------------------------------------------------------- tag-title-case: description: Tag names must be Title Case (e.g. Recipes, Meal Planning, Menu Items). severity: warn given: $.paths[*][get,post,put,delete,patch].tags[*] then: function: pattern functionOptions: match: "^[A-Z][A-Za-z]*( [A-Z][A-Za-z]*)*$" # --------------------------------------------------------------- # PARAMETERS # --------------------------------------------------------------- parameter-description-required: description: Parameters should have a description. severity: info given: $.paths[*][get,post,put,delete,patch].parameters[*] then: field: description function: truthy parameter-schema-typed: description: Parameters must define a typed schema. severity: warn given: $.paths[*][get,post,put,delete,patch].parameters[*].schema then: field: type function: truthy # --------------------------------------------------------------- # RESPONSES # --------------------------------------------------------------- response-success-defined: description: Operations must define a 200 (or 2xx) success response. severity: warn given: $.paths[*][get,post,put,delete,patch].responses then: field: "200" function: truthy # --------------------------------------------------------------- # SECURITY # --------------------------------------------------------------- security-global-defined: description: A global security requirement must be declared. severity: warn given: $ then: field: security function: truthy security-apikey-header: description: The API key security scheme must be an apiKey delivered in the x-api-key header. severity: error given: $.components.securitySchemes.apiKeyScheme then: - field: type function: pattern functionOptions: match: "^apiKey$" - field: in function: pattern functionOptions: match: "^header$" - field: name function: pattern functionOptions: match: "^x-api-key$" # --------------------------------------------------------------- # GENERAL QUALITY # --------------------------------------------------------------- operation-examples-encouraged: description: Operations are encouraged to provide response examples for mocking. severity: info given: $.paths[*][get,post,put,delete,patch].responses[*].content[*] then: function: defined field: examples