SpaceX (Community API) · API Governance Rules

SpaceX (Community API) API Rules

Spectral linting rules defining API design standards and conventions for SpaceX (Community API).

32 Rules error 10 warn 15 info 7
View Rules File View on GitHub

Rule Categories

spacex

Rules

warn
spacex-info-title
Title must start with "SpaceX" (community API convention).
$.info.title
error
spacex-info-description-required
Info description is required and must be non-trivial.
$.info
warn
spacex-info-license-apache2
License should be Apache 2.0 to match upstream project.
$.info.license.name
info
spacex-info-status-maintenance
Community SpaceX-API is in maintenance-only mode; mark with x-status.
$.info
error
spacex-openapi-version-3
Use OpenAPI 3.x.
$.openapi
error
spacex-servers-defined
At least one server must be defined.
$.servers
error
spacex-server-https
Hosted server URL must use HTTPS.
$.servers[*].url
info
spacex-server-spacexdata
Canonical hosted server is https://api.spacexdata.com.
$.servers[*].url
error
spacex-paths-versioned
All paths must be prefixed with /v4 or /v5.
$.paths.*~
warn
spacex-paths-kebab-case
Path segments use lowercase letters, digits, and hyphens only (kebab-case).
$.paths.*~
info
spacex-paths-plural-collections
Top-level resource collections should be plural nouns.
$.paths.*~
error
spacex-paths-no-trailing-slash
Paths must not end with a trailing slash.
$.paths.*~
error
spacex-operation-operationid
Every operation must have an operationId.
$.paths.*[get,post,put,patch,delete]
warn
spacex-operation-operationid-camelcase
operationId must be camelCase.
$.paths.*[get,post,put,patch,delete].operationId
warn
spacex-operation-summary
Every operation must have a summary in Title Case.
$.paths.*[get,post,put,patch,delete]
warn
spacex-operation-description
Every operation must have a description.
$.paths.*[get,post,put,patch,delete]
warn
spacex-operation-tags
Every operation must have at least one tag.
$.paths.*[get,post,put,patch,delete]
warn
spacex-tags-known
Operation tags should be one of the documented resource tags.
$.paths.*[get,post,put,patch,delete].tags[*]
warn
spacex-parameter-description
All parameters must have descriptions.
$.paths.*[get,post,put,patch,delete].parameters[*]
warn
spacex-parameter-id-snake-case
Path parameter names must be snake_case or single-word.
$.paths.*[get,post,put,patch,delete].parameters[?(@.in=='path')].name
warn
spacex-requestbody-json
Request bodies must offer application/json.
$.paths.*[post,put,patch].requestBody.content
error
spacex-response-success
Every operation must declare at least one 2xx response.
$.paths.*[get,post,put,patch,delete].responses
warn
spacex-response-description
Every response must have a description.
$.paths.*[get,post,put,patch,delete].responses.*
info
spacex-response-not-found
GET-by-id operations should declare a 404 response.
$.paths[?(@property =~ /\\{id\\}$/)].get.responses
warn
spacex-schema-snake-case-properties
Schema properties should be snake_case (mongoose model convention).
$.components.schemas.*.properties.*~
info
spacex-schema-id-property
Resource schemas should expose an `id` property (UUID).
$.components.schemas[?(@property =~ /^(Launch|Rocket|Capsule|Core|CrewMember|Dragon|Payload|Ship|Launchpad|Landpad|StarlinkSat|Roadster|Company|HistoryEvent)$/)].properties
warn
spacex-security-scheme-defined
At least one security scheme must be defined (for admin routes).
$.components.securitySchemes
info
spacex-security-spacex-key
Admin auth header is `spacex-key`.
$.components.securitySchemes[?(@.type=='apiKey' && @.in=='header')].name
error
spacex-get-no-requestbody
GET operations must not declare a requestBody.
$.paths.*.get
error
spacex-query-uses-post
/query endpoints must use POST (mongoose-paginate query body).
$.paths[?(@property =~ /\\/query$/)]
warn
spacex-no-empty-description
Descriptions must not be empty strings.
$..description
info
spacex-microcks-extension
Each operation should include x-microcks-operation for mocking.
$.paths.*[get,post,put,patch,delete]

Spectral Ruleset

Raw ↑
extends:
  - spectral:oas
formats:
  - oas3
rules:
  # ===== INFO / METADATA =====
  spacex-info-title:
    description: Title must start with "SpaceX" (community API convention).
    message: '{{property}} should start with "SpaceX"'
    severity: warn
    given: $.info.title
    then:
      function: pattern
      functionOptions:
        match: '^SpaceX( |$)'
  spacex-info-description-required:
    description: Info description is required and must be non-trivial.
    message: 'info.description must be present (>= 40 chars).'
    severity: error
    given: $.info
    then:
      field: description
      function: length
      functionOptions:
        min: 40
  spacex-info-license-apache2:
    description: License should be Apache 2.0 to match upstream project.
    severity: warn
    given: $.info.license.name
    then:
      function: pattern
      functionOptions:
        match: '^Apache 2\\.0$'
  spacex-info-status-maintenance:
    description: Community SpaceX-API is in maintenance-only mode; mark with x-status.
    severity: info
    given: $.info
    then:
      field: x-status
      function: truthy

  # ===== OPENAPI VERSION =====
  spacex-openapi-version-3:
    description: Use OpenAPI 3.x.
    severity: error
    given: $.openapi
    then:
      function: pattern
      functionOptions:
        match: '^3\\.'

  # ===== SERVERS =====
  spacex-servers-defined:
    description: At least one server must be defined.
    severity: error
    given: $.servers
    then:
      function: length
      functionOptions:
        min: 1
  spacex-server-https:
    description: Hosted server URL must use HTTPS.
    severity: error
    given: $.servers[*].url
    then:
      function: pattern
      functionOptions:
        match: '^https://'
  spacex-server-spacexdata:
    description: Canonical hosted server is https://api.spacexdata.com.
    severity: info
    given: $.servers[*].url
    then:
      function: pattern
      functionOptions:
        match: 'api\\.spacexdata\\.com'

  # ===== PATHS — NAMING CONVENTIONS =====
  spacex-paths-versioned:
    description: All paths must be prefixed with /v4 or /v5.
    severity: error
    given: $.paths.*~
    then:
      function: pattern
      functionOptions:
        match: '^/v[45]/'
  spacex-paths-kebab-case:
    description: Path segments use lowercase letters, digits, and hyphens only (kebab-case).
    severity: warn
    given: $.paths.*~
    then:
      function: pattern
      functionOptions:
        match: '^/[a-z0-9/{}_-]+$'
  spacex-paths-plural-collections:
    description: Top-level resource collections should be plural nouns.
    severity: info
    given: $.paths.*~
    then:
      function: pattern
      functionOptions:
        match: '^/v[45]/(capsules|company|cores|crew|dragons|history|landpads|launches|launchpads|payloads|roadster|rockets|ships|starlink)(/.*)?$'
  spacex-paths-no-trailing-slash:
    description: Paths must not end with a trailing slash.
    severity: error
    given: $.paths.*~
    then:
      function: pattern
      functionOptions:
        notMatch: '/$'

  # ===== OPERATIONS =====
  spacex-operation-operationid:
    description: Every operation must have an operationId.
    severity: error
    given: $.paths.*[get,post,put,patch,delete]
    then:
      field: operationId
      function: truthy
  spacex-operation-operationid-camelcase:
    description: operationId must be camelCase.
    severity: warn
    given: $.paths.*[get,post,put,patch,delete].operationId
    then:
      function: pattern
      functionOptions:
        match: '^[a-z][a-zA-Z0-9]*$'
  spacex-operation-summary:
    description: Every operation must have a summary in Title Case.
    severity: warn
    given: $.paths.*[get,post,put,patch,delete]
    then:
      field: summary
      function: truthy
  spacex-operation-description:
    description: Every operation must have a description.
    severity: warn
    given: $.paths.*[get,post,put,patch,delete]
    then:
      field: description
      function: truthy
  spacex-operation-tags:
    description: Every operation must have at least one tag.
    severity: warn
    given: $.paths.*[get,post,put,patch,delete]
    then:
      field: tags
      function: length
      functionOptions:
        min: 1

  # ===== TAGS =====
  spacex-tags-known:
    description: Operation tags should be one of the documented resource tags.
    severity: warn
    given: $.paths.*[get,post,put,patch,delete].tags[*]
    then:
      function: enumeration
      functionOptions:
        values:
          - Capsules
          - Company
          - Cores
          - Crew
          - Dragons
          - History
          - Landpads
          - Launches
          - Launchpads
          - Payloads
          - Roadster
          - Rockets
          - Ships
          - Starlink

  # ===== PARAMETERS =====
  spacex-parameter-description:
    description: All parameters must have descriptions.
    severity: warn
    given: $.paths.*[get,post,put,patch,delete].parameters[*]
    then:
      field: description
      function: truthy
  spacex-parameter-id-snake-case:
    description: Path parameter names must be snake_case or single-word.
    severity: warn
    given: $.paths.*[get,post,put,patch,delete].parameters[?(@.in=='path')].name
    then:
      function: pattern
      functionOptions:
        match: '^[a-z][a-z0-9_]*$'

  # ===== REQUEST BODIES =====
  spacex-requestbody-json:
    description: Request bodies must offer application/json.
    severity: warn
    given: $.paths.*[post,put,patch].requestBody.content
    then:
      field: application/json
      function: truthy

  # ===== RESPONSES =====
  spacex-response-success:
    description: Every operation must declare at least one 2xx response.
    severity: error
    given: $.paths.*[get,post,put,patch,delete].responses
    then:
      function: schema
      functionOptions:
        schema:
          type: object
          patternProperties:
            '^2[0-9][0-9]$':
              type: object
          additionalProperties: true
          minProperties: 1
  spacex-response-description:
    description: Every response must have a description.
    severity: warn
    given: $.paths.*[get,post,put,patch,delete].responses.*
    then:
      field: description
      function: truthy
  spacex-response-not-found:
    description: GET-by-id operations should declare a 404 response.
    severity: info
    given: $.paths[?(@property =~ /\\{id\\}$/)].get.responses
    then:
      field: '404'
      function: truthy

  # ===== SCHEMAS — PROPERTY NAMING =====
  spacex-schema-snake-case-properties:
    description: Schema properties should be snake_case (mongoose model convention).
    severity: warn
    given: $.components.schemas.*.properties.*~
    then:
      function: pattern
      functionOptions:
        match: '^[a-z][a-z0-9_]*$|^[A-Z][A-Z0-9_]*$'
  spacex-schema-id-property:
    description: Resource schemas should expose an `id` property (UUID).
    severity: info
    given: '$.components.schemas[?(@property =~ /^(Launch|Rocket|Capsule|Core|CrewMember|Dragon|Payload|Ship|Launchpad|Landpad|StarlinkSat|Roadster|Company|HistoryEvent)$/)].properties'
    then:
      field: id
      function: truthy

  # ===== SECURITY =====
  spacex-security-scheme-defined:
    description: At least one security scheme must be defined (for admin routes).
    severity: warn
    given: $.components.securitySchemes
    then:
      function: truthy
  spacex-security-spacex-key:
    description: Admin auth header is `spacex-key`.
    severity: info
    given: $.components.securitySchemes[?(@.type=='apiKey' && @.in=='header')].name
    then:
      function: pattern
      functionOptions:
        match: '^spacex-key$'

  # ===== HTTP METHOD CONVENTIONS =====
  spacex-get-no-requestbody:
    description: GET operations must not declare a requestBody.
    severity: error
    given: $.paths.*.get
    then:
      field: requestBody
      function: falsy
  spacex-query-uses-post:
    description: /query endpoints must use POST (mongoose-paginate query body).
    severity: error
    given: '$.paths[?(@property =~ /\\/query$/)]'
    then:
      field: post
      function: truthy

  # ===== GENERAL QUALITY =====
  spacex-no-empty-description:
    description: Descriptions must not be empty strings.
    severity: warn
    given: $..description
    then:
      function: length
      functionOptions:
        min: 1
  spacex-microcks-extension:
    description: Each operation should include x-microcks-operation for mocking.
    severity: info
    given: $.paths.*[get,post,put,patch,delete]
    then:
      field: x-microcks-operation
      function: truthy