Class: DocsKit::OpenApi::Operation

Inherits:
Object
  • Object
show all
Defined in:
lib/docs_kit/open_api/operation.rb

Overview

One OpenAPI operation (a path + verb), exposing exactly the shapes the kit's render targets consume:

#parameter_rows / #body_rows → DocsUI::FieldTable
#error_rows                  → DocsUI::ErrorTable
#example_body / #success_example → DocsUI::JsonResponse / RequestExample body
#example_path / #example_query   → the RequestExample snippet URL
#code_samples                → DocsUI::Example tabs (x-codeSamples)

It never renders — it's the bridge value object DocsUI::OpenApiOperation reads. All schema traversal delegates to DocsKit::OpenApi::Schema.

Constant Summary collapse

CODE_SAMPLE_KEYS =

Both spellings of the code-samples vendor extension seen in the wild (Redoc uses x-codeSamples; older tooling x-code-samples).

%w[x-codeSamples x-code-samples].freeze
JSON_MEDIA_TYPE =

The media type the bridge reads bodies/examples from.

"application/json"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(document, method:, path:, raw:) ⇒ Operation

Returns a new instance of Operation.



25
26
27
28
29
30
# File 'lib/docs_kit/open_api/operation.rb', line 25

def initialize(document, method:, path:, raw:)
  @document = document
  @method = method
  @path = path
  @raw = raw
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



23
24
25
# File 'lib/docs_kit/open_api/operation.rb', line 23

def path
  @path
end

Instance Method Details

#body_rowsObject

FieldTable rows for the request-body schema (flattened, nested-dotted).



56
57
58
59
60
61
# File 'lib/docs_kit/open_api/operation.rb', line 56

def body_rows
  schema = request_body_schema
  return [] unless schema

  Schema.new(@document, schema).rows
end

#code_samplesObject

x-codeSamples entries as { lang:, label:, source: } (either spelling).



120
121
122
123
124
125
126
127
128
# File 'lib/docs_kit/open_api/operation.rb', line 120

def code_samples
  raw_samples.map do |sample|
    {
      lang: sample["lang"],
      label: sample["label"],
      source: sample["source"].to_s
    }
  end
end

#deprecated?Boolean

Returns:

  • (Boolean)


36
# File 'lib/docs_kit/open_api/operation.rb', line 36

def deprecated? = @raw["deprecated"] == true

#descriptionObject



35
# File 'lib/docs_kit/open_api/operation.rb', line 35

def description = @raw["description"]

#error_rowsObject

ErrorTable rows for the 4xx/5xx responses: status + scenario (the response description) + an optional error type read from the response example.



65
66
67
68
69
70
71
72
73
# File 'lib/docs_kit/open_api/operation.rb', line 65

def error_rows
  error_responses.map do |status, response|
    {
      status: status,
      scenario: response_description(response),
      type: error_type_for(response)
    }
  end
end

#example_bodyObject

A synthesized (or explicit) request body example Hash, or nil when the operation has no request body.



77
78
79
80
81
82
83
84
85
# File 'lib/docs_kit/open_api/operation.rb', line 77

def example_body
  schema = request_body_schema
  return unless schema

  media = request_body_media
  return media["example"] if media&.key?("example")

  first_examples_value(media) || Schema.new(@document, schema).example_value
end

#example_pathObject

The path with each path-parameter placeholder replaced by its example (copy-pasteable), leaving placeholders without an example untouched.



89
90
91
92
93
94
95
96
# File 'lib/docs_kit/open_api/operation.rb', line 89

def example_path
  path.gsub(/\{(\w+)\}/) do
    name = Regexp.last_match(1)
    param = path_parameters.find { |p| p["name"] == name }
    example = param && param["example"]
    example.nil? ? "{#{name}}" : example.to_s
  end
end

#example_queryObject

{ name => value } for query params that carry an explicit example (never invent a value for a required-but-example-less param — it stays doc-only).



100
101
102
103
104
# File 'lib/docs_kit/open_api/operation.rb', line 100

def example_query
  query_parameters.each_with_object({}) do |param, acc|
    acc[param["name"]] = param["example"] if param.key?("example")
  end
end

#http_methodObject



32
# File 'lib/docs_kit/open_api/operation.rb', line 32

def http_method = @method.to_s.upcase

#operation_idObject



33
# File 'lib/docs_kit/open_api/operation.rb', line 33

def operation_id = @raw["operationId"]

#parameter_rowsObject

FieldTable rows for the operation's query/path/header parameters.



44
45
46
47
48
49
50
51
52
53
# File 'lib/docs_kit/open_api/operation.rb', line 44

def parameter_rows
  parameters.map do |param|
    {
      name: param["name"],
      type: Schema.new(@document, param["schema"]).type_label,
      required: param["required"] == true,
      description: description_cell(param["description"])
    }
  end
end

#success_exampleObject

The first 2xx response's example body (explicit or synthesized), or nil.



107
108
109
110
111
112
113
114
115
116
117
# File 'lib/docs_kit/open_api/operation.rb', line 107

def success_example
  _, response = success_response
  return unless response

  media = json_media(response)
  return unless media

  return media["example"] if media.key?("example")

  first_examples_value(media) || example_from_schema(media["schema"])
end

#summaryObject



34
# File 'lib/docs_kit/open_api/operation.rb', line 34

def summary = @raw["summary"]

#titleObject

The section title: the summary, else the operationId, else the verb+path.



39
40
41
# File 'lib/docs_kit/open_api/operation.rb', line 39

def title
  summary || operation_id || "#{http_method} #{path}"
end