Lightspeed · API Governance Rules

Lightspeed API Rules

Spectral linting rules defining API design standards and conventions for Lightspeed.

28 Rules error 6 warn 12 info 10
View Rules File View on GitHub

Rule Categories

delete get info openapi operation parameter paths request response schema security servers tag

Rules

warn
info-title-lightspeed-prefix
API title should start with "Lightspeed".
$.info
warn
info-description-required
Info object must have a non-trivial description.
$.info
error
info-version-required
Info object must declare a version.
$.info
info
info-contact-required
Info object should include a contact.
$.info
warn
openapi-version-3-1
Lightspeed specs target OpenAPI 3.1.x.
$
error
servers-defined
At least one server must be defined.
$
error
servers-https
Server URLs must use HTTPS.
$.servers[*]
info
servers-lightspeed-host
Server URLs should point at a lightspeed host.
$.servers[*]
warn
paths-no-trailing-slash
Paths must not end with a trailing slash.
$.paths
error
paths-no-query-string
Path keys must not contain query strings.
$.paths
warn
operation-summary-required
Every operation must have a summary.
$.paths[*][get,post,put,patch,delete]
info
operation-summary-lightspeed-prefix
Operation summaries should be prefixed with "Lightspeed".
$.paths[*][get,post,put,patch,delete]
info
operation-description-required
Every operation should have a description.
$.paths[*][get,post,put,patch,delete]
error
operation-operationid-required
Every operation must have an operationId.
$.paths[*][get,post,put,patch,delete]
warn
operation-operationid-camelcase
operationId should be camelCase (Lightspeed convention).
$.paths[*][get,post,put,patch,delete]
warn
operation-tags-required
Every operation must be tagged.
$.paths[*][get,post,put,patch,delete]
info
tag-title-case
Global tag names should use Title Case.
$.tags[*]
info
parameter-description-required
Parameters should have descriptions.
$.paths[*][get,post,put,patch,delete].parameters[?(@.name)]
warn
parameter-schema-typed
Parameters must define a typed schema.
$.paths[*][get,post,put,patch,delete].parameters[?(@.name && @.schema)]
info
request-body-json
Request bodies should offer application/json.
$.paths[*][post,put,patch].requestBody.content
warn
response-success-defined
Operations must define at least one 2xx response.
$.paths[*][get,post,put,patch,delete].responses
warn
response-description-required
Every response must have a description.
$.paths[*][get,post,put,patch,delete].responses[*]
info
schema-type-defined
Component schemas should declare a type.
$.components.schemas[*]
warn
security-global-defined
A global security requirement should be declared.
$
info
security-schemes-oauth2
Lightspeed POS APIs authenticate with OAuth 2.0.
$.components.securitySchemes[*]
error
get-no-request-body
GET operations must not declare a request body.
$.paths[*].get
warn
delete-no-request-body
DELETE operations must not declare a request body.
$.paths[*].delete
info
operation-microcks-extension
Operations should carry an x-microcks-operation extension for mocking.
$.paths[*][get,post,put,patch,delete]

Spectral Ruleset

Raw ↑
# Spectral ruleset for the Lightspeed Commerce POS APIs (Restaurant K-Series,
# Retail R-Series, Retail X-Series). Derived from the conventions observed
# across the OpenAPI specs in openapi/. Opinionated: enforces the dominant
# pattern even where individual specs deviate.
#
# Run: spectral lint openapi/*.yml --ruleset rules/lightspeed-pos-spectral-rules.yml

extends: [[spectral:oas, off]]

rules:

  # ─────────────────────────────────────────────────────────────
  # INFO / METADATA
  # ─────────────────────────────────────────────────────────────
  info-title-lightspeed-prefix:
    description: API title should start with "Lightspeed".
    severity: warn
    given: $.info
    then:
      field: title
      function: pattern
      functionOptions:
        match: "^Lightspeed"

  info-description-required:
    description: Info object must have a non-trivial description.
    severity: warn
    given: $.info
    then:
      field: description
      function: length
      functionOptions:
        min: 40

  info-version-required:
    description: Info object must declare a version.
    severity: error
    given: $.info
    then:
      field: version
      function: truthy

  info-contact-required:
    description: Info object should include a contact.
    severity: info
    given: $.info
    then:
      field: contact
      function: truthy

  # ─────────────────────────────────────────────────────────────
  # OPENAPI VERSION
  # ─────────────────────────────────────────────────────────────
  openapi-version-3-1:
    description: Lightspeed specs target OpenAPI 3.1.x.
    severity: warn
    given: $
    then:
      field: openapi
      function: pattern
      functionOptions:
        match: "^3\\.1\\."

  # ─────────────────────────────────────────────────────────────
  # SERVERS
  # ─────────────────────────────────────────────────────────────
  servers-defined:
    description: At least one server 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://"

  servers-lightspeed-host:
    description: Server URLs should point at a lightspeed host.
    severity: info
    given: $.servers[*]
    then:
      field: url
      function: pattern
      functionOptions:
        match: "lightspeed"

  # ─────────────────────────────────────────────────────────────
  # PATHS
  # ─────────────────────────────────────────────────────────────
  paths-no-trailing-slash:
    description: Paths must not end with a trailing slash.
    severity: warn
    given: $.paths
    then:
      field: "@key"
      function: pattern
      functionOptions:
        notMatch: ".+/$"

  paths-no-query-string:
    description: Path keys must not contain query strings.
    severity: error
    given: $.paths
    then:
      field: "@key"
      function: pattern
      functionOptions:
        notMatch: "\\?"

  # ─────────────────────────────────────────────────────────────
  # OPERATIONS
  # ─────────────────────────────────────────────────────────────
  operation-summary-required:
    description: Every operation must have a summary.
    severity: warn
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: summary
      function: truthy

  operation-summary-lightspeed-prefix:
    description: Operation summaries should be prefixed with "Lightspeed".
    severity: info
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: summary
      function: pattern
      functionOptions:
        match: "^Lightspeed"

  operation-description-required:
    description: Every operation should have a description.
    severity: info
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: description
      function: truthy

  operation-operationid-required:
    description: Every operation must have an operationId.
    severity: error
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: operationId
      function: truthy

  operation-operationid-camelcase:
    description: operationId should be camelCase (Lightspeed convention).
    severity: warn
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: operationId
      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,patch,delete]
    then:
      field: tags
      function: truthy

  # ─────────────────────────────────────────────────────────────
  # TAGS
  # ─────────────────────────────────────────────────────────────
  tag-title-case:
    description: Global tag names should use Title Case.
    severity: info
    given: $.tags[*]
    then:
      field: name
      function: pattern
      functionOptions:
        match: "^[A-Z0-9]"

  # ─────────────────────────────────────────────────────────────
  # PARAMETERS
  # ─────────────────────────────────────────────────────────────
  parameter-description-required:
    description: Parameters should have descriptions.
    severity: info
    given: $.paths[*][get,post,put,patch,delete].parameters[?(@.name)]
    then:
      field: description
      function: truthy

  parameter-schema-typed:
    description: Parameters must define a typed schema.
    severity: warn
    given: $.paths[*][get,post,put,patch,delete].parameters[?(@.name && @.schema)]
    then:
      field: schema.type
      function: truthy

  # ─────────────────────────────────────────────────────────────
  # REQUEST BODIES
  # ─────────────────────────────────────────────────────────────
  request-body-json:
    description: Request bodies should offer application/json.
    severity: info
    given: $.paths[*][post,put,patch].requestBody.content
    then:
      field: application/json
      function: truthy

  # ─────────────────────────────────────────────────────────────
  # RESPONSES
  # ─────────────────────────────────────────────────────────────
  response-success-defined:
    description: Operations must define at least one 2xx response.
    severity: warn
    given: $.paths[*][get,post,put,patch,delete].responses
    then:
      field: "@key"
      function: pattern
      functionOptions:
        match: "2[0-9][0-9]"

  response-description-required:
    description: Every response must have a description.
    severity: warn
    given: $.paths[*][get,post,put,patch,delete].responses[*]
    then:
      field: description
      function: truthy

  # ─────────────────────────────────────────────────────────────
  # SCHEMAS
  # ─────────────────────────────────────────────────────────────
  schema-type-defined:
    description: Component schemas should declare a type.
    severity: info
    given: $.components.schemas[*]
    then:
      field: type
      function: truthy

  # ─────────────────────────────────────────────────────────────
  # SECURITY
  # ─────────────────────────────────────────────────────────────
  security-global-defined:
    description: A global security requirement should be declared.
    severity: warn
    given: $
    then:
      field: security
      function: truthy

  security-schemes-oauth2:
    description: Lightspeed POS APIs authenticate with OAuth 2.0.
    severity: info
    given: $.components.securitySchemes[*]
    then:
      field: type
      function: pattern
      functionOptions:
        match: "oauth2"

  # ─────────────────────────────────────────────────────────────
  # HTTP METHOD CONVENTIONS
  # ─────────────────────────────────────────────────────────────
  get-no-request-body:
    description: GET operations must not declare a request body.
    severity: error
    given: $.paths[*].get
    then:
      field: requestBody
      function: falsy

  delete-no-request-body:
    description: DELETE operations must not declare a request body.
    severity: warn
    given: $.paths[*].delete
    then:
      field: requestBody
      function: falsy

  # ─────────────────────────────────────────────────────────────
  # MICROCKS / MOCKING
  # ─────────────────────────────────────────────────────────────
  operation-microcks-extension:
    description: Operations should carry an x-microcks-operation extension for mocking.
    severity: info
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: x-microcks-operation
      function: truthy