Princeton University · API Governance Rules

Princeton University API Rules

Spectral linting rules defining API design standards and conventions for Princeton University.

9 Rules error 2 warn 7
View Rules File View on GitHub

Rule Categories

info operation response root server

Rules

error
operation-has-operationid
Every operation should declare an operationId. Princeton does this 14/14.
$.paths[*][get,post,put,patch,delete]
warn
operation-operationid-verb-case
operationIds follow this API's own convention — a lowercase verb followed by a CapitalCase target (searchCatalog, displayBanner).
$.paths[*][get,post,put,patch,delete].operationId
warn
operation-has-summary
Every operation should carry a summary.
$.paths[*][get,post,put,patch,delete]
warn
operation-has-description
Every operation should carry a description beyond its summary.
$.paths[*][get,post,put,patch,delete]
warn
operation-has-tags
Every operation should be tagged so the contract splits cleanly by resource.
$.paths[*][get,post,put,patch,delete]
warn
response-content-has-example
Every response media type should carry an example. This is the strongest habit in Princeton's contract — 32 of 32 content entries ship one, which is what makes the document usable without a schema section.
$.paths[*][get,post,put,patch,delete].responses[*].content[*]
error
server-is-princeton-operated
Server URLs must resolve under princeton.edu. This is the operator rule: a contract catalogued under Princeton must describe a host Princeton runs, not a vendor platform the institution merely subscribes to.
$.servers[*].url
warn
info-has-contact
info.contact should name a maintainer and a URL. Currently absent — the document is machine-generated from request specs and never had one added.
$.info
warn
root-declares-tags
Root-level tags[] should declare and describe every tag the operations use. Fourteen tags are in use and none are declared, so a consumer gets group names with no definitions.
$

Spectral Ruleset

Raw ↑
# authorship: generated by API Evangelist tooling. Stamped 2026-08-19.
# An unmarked file is NOT assumed to be ours.
x-method: generated
x-source: openapi/_original/princeton-allsearch-api-openapi.yml
x-operator: institution
# Princeton University Library — OpenAPI Spectral ruleset.
# Plain Spectral, built-in functions only. Rules were MEASURED from Princeton's own
# published Allsearch OpenAPI 3.1.1, not imported from a house style, then checked back
# against that document.
#
# Measured on 2026-08-19 across 14 operations / 32 response content entries:
#   operation-has-operationid        14/14  (100%)
#   operation-operationid-verb-case  14/14  (100%, ^(search|display)[A-Z])
#   operation-has-summary            14/14  (100%)
#   operation-has-description        14/14  (100%)
#   operation-has-tags               14/14  (100%)
#   response-content-has-example     32/32  (100%)
#   server-is-princeton-operated      2/2   (100%)
#   info-has-contact                  0/1   (FAILS — the one real gap in an otherwise
#                                     unusually complete institutional contract)
#   root-declares-tags                0/1   (FAILS — 14 tags are used, none declared)
rules:
  operation-has-operationid:
    description: Every operation should declare an operationId. Princeton does this 14/14.
    severity: error
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: operationId
      function: truthy

  operation-operationid-verb-case:
    description: >-
      operationIds follow this API's own convention — a lowercase verb followed by a
      CapitalCase target (searchCatalog, displayBanner).
    severity: warn
    given: $.paths[*][get,post,put,patch,delete].operationId
    then:
      function: pattern
      functionOptions:
        match: "^(search|display|get|list|create|update|delete)[A-Z][A-Za-z]*$"

  operation-has-summary:
    description: Every operation should carry a summary.
    severity: warn
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: summary
      function: truthy

  operation-has-description:
    description: Every operation should carry a description beyond its summary.
    severity: warn
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: description
      function: truthy

  operation-has-tags:
    description: Every operation should be tagged so the contract splits cleanly by resource.
    severity: warn
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: tags
      function: truthy

  response-content-has-example:
    description: >-
      Every response media type should carry an example. This is the strongest habit in
      Princeton's contract — 32 of 32 content entries ship one, which is what makes the
      document usable without a schema section.
    severity: warn
    given: $.paths[*][get,post,put,patch,delete].responses[*].content[*]
    then:
      field: example
      function: truthy

  server-is-princeton-operated:
    description: >-
      Server URLs must resolve under princeton.edu. This is the operator rule: a contract
      catalogued under Princeton must describe a host Princeton runs, not a vendor platform
      the institution merely subscribes to.
    severity: error
    given: $.servers[*].url
    then:
      function: pattern
      functionOptions:
        match: "princeton\\.edu"

  info-has-contact:
    description: >-
      info.contact should name a maintainer and a URL. Currently absent — the document is
      machine-generated from request specs and never had one added.
    severity: warn
    given: $.info
    then:
      field: contact
      function: truthy

  root-declares-tags:
    description: >-
      Root-level tags[] should declare and describe every tag the operations use. Fourteen
      tags are in use and none are declared, so a consumer gets group names with no definitions.
    severity: warn
    given: $
    then:
      field: tags
      function: truthy