jService · API Governance Rules

jService API Rules

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

11 Rules error 6 warn 5
View Rules File View on GitHub

Rule Categories

jservice

Rules

error
jservice-operation-id-camelcase
operationId must be camelCase (matches jService's existing operationIds).
$.paths.*[get,post,put,patch,delete].operationId
error
jservice-snake-case-properties
Schema properties must be snake_case (matches Rails/ActiveRecord JSON output).
$.components.schemas.*.properties.*~
error
jservice-snake-case-query-params
Query parameters must be snake_case.
$.paths.*[get,post,put,patch,delete].parameters[?(@.in=='query')].name
warn
jservice-summary-title-case
Operation summary should be Title Case.
$.paths.*[get,post,put,patch,delete].summary
error
jservice-summary-required
Every operation must have a summary.
$.paths.*[get,post,put,patch,delete]
warn
jservice-description-required
Every operation must have a description.
$.paths.*[get,post,put,patch,delete]
error
jservice-tag-required
Every operation must be tagged.
$.paths.*[get,post,put,patch,delete]
warn
jservice-allowed-tags
Operations must use one of the known jService tags.
$.paths.*[get,post,put,patch,delete].tags[*]
warn
jservice-paths-under-api
All operational paths live under /api/.
$.paths
warn
jservice-pagination-max-100
count/offset limits should mirror the source code (count <= 100).
$.paths.*.get.parameters[?(@.name=='count')].schema
error
jservice-json-only
jService responds only in application/json.
$.paths.*[get,post,put,patch,delete].responses.*.content

Spectral Ruleset

Raw ↑
extends:
  - spectral:oas
documentationUrl: https://github.com/sottenad/jService
formats:
  - oas3
rules:
  # ----- Naming conventions -----
  jservice-operation-id-camelcase:
    description: operationId must be camelCase (matches jService's existing operationIds).
    given: $.paths.*[get,post,put,patch,delete].operationId
    severity: error
    then:
      function: pattern
      functionOptions:
        match: '^[a-z][a-zA-Z0-9]*$'

  jservice-snake-case-properties:
    description: Schema properties must be snake_case (matches Rails/ActiveRecord JSON output).
    given: $.components.schemas.*.properties.*~
    severity: error
    then:
      function: pattern
      functionOptions:
        match: '^[a-z][a-z0-9_]*$'

  jservice-snake-case-query-params:
    description: Query parameters must be snake_case.
    given: $.paths.*[get,post,put,patch,delete].parameters[?(@.in=='query')].name
    severity: error
    then:
      function: pattern
      functionOptions:
        match: '^[a-z][a-z0-9_]*$'

  # ----- Summaries and descriptions -----
  jservice-summary-title-case:
    description: Operation summary should be Title Case.
    given: $.paths.*[get,post,put,patch,delete].summary
    severity: warn
    then:
      function: pattern
      functionOptions:
        match: '^([A-Z][A-Za-z0-9]*)(\s+[A-Z][A-Za-z0-9]*)*$'

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

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

  # ----- Tagging -----
  jservice-tag-required:
    description: Every operation must be tagged.
    given: $.paths.*[get,post,put,patch,delete]
    severity: error
    then:
      field: tags
      function: truthy

  jservice-allowed-tags:
    description: Operations must use one of the known jService tags.
    given: $.paths.*[get,post,put,patch,delete].tags[*]
    severity: warn
    then:
      function: enumeration
      functionOptions:
        values: [Clues, Categories, Moderation]

  # ----- API surface conventions -----
  jservice-paths-under-api:
    description: All operational paths live under /api/.
    given: $.paths
    severity: warn
    then:
      function: pattern
      field: '@key'
      functionOptions:
        match: '^/api/'

  jservice-pagination-max-100:
    description: count/offset limits should mirror the source code (count <= 100).
    given: $.paths.*.get.parameters[?(@.name=='count')].schema
    severity: warn
    then:
      field: maximum
      function: truthy

  # ----- JSON only -----
  jservice-json-only:
    description: jService responds only in application/json.
    given: $.paths.*[get,post,put,patch,delete].responses.*.content
    severity: error
    then:
      function: pattern
      field: '@key'
      functionOptions:
        match: '^application/json'