Class: WebFunction::Endpoint

Inherits:
Object
  • Object
show all
Defined in:
lib/web_function/endpoint.rb

Overview

# Endpoint

Represents an endpoint as described in a Web Function package.

An endpoint defines an operation that can be performed via a Web Function API. Endpoints declare their name, documentation, arguments (inputs), attributes (outputs), and the possible errors that may occur when invoking them.

Endpoints are described as objects in each package under the ‘“endpoints”` key. For more information, see:

This class provides methods for accessing endpoint metadata (name, docs, arguments, attributes, errors) and supports invocation via HTTP.

Typical tasks include:

  • Querying endpoint name or documentation

  • Enumerating the arguments or attributes definitions

  • Invoking the endpoint through HTTP using required inputs

See: webfunction.org/endpoint for more details on endpoint structure and contract.

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(endpoint) ⇒ Endpoint

Returns a new instance of Endpoint.



28
29
30
# File 'lib/web_function/endpoint.rb', line 28

def initialize(endpoint)
  @endpoint = endpoint
end

Class Attribute Details

.http_clientProc

## HTTP client getter

The HTTP client used to invoke the endpoint.

Returns:

  • (Proc)


39
40
41
42
43
44
45
46
47
# File 'lib/web_function/endpoint.rb', line 39

def http_client
  @http_client ||= proc do |url, headers, body|
    response = Excon.post(url,
      headers: headers,
      body: body,
    )
    [response.status, response.body]
  end
end

Class Method Details

.invoke(url, bearer_auth: nil, args: {}) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/web_function/endpoint.rb', line 99

def invoke(url, bearer_auth: nil, args: {})
  headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
    "User-Agent": "webfunction/#{WebFunction::VERSION}",
  }

  if args.nil?
    args = {}
  end

  if bearer_auth
    headers["Authorization"] = "Bearer #{bearer_auth}"
  end

  status, body = http_client.call(url, headers, JSON.generate(args))

  unless [200, 400].include?(status)
    raise WebFunction::UnexpectedStatusCodeError.new("Unexpected status code (#{status})",
      details: {
        status_code: status,
        raw_body: body,
      },
    )
  end

  begin
    result = JSON.parse(body)
  rescue JSON::ParserError => e
    raise WebFunction::JsonParseError.new(e.message,
      details: {
        status_code: status,
        raw_body: body,
        original_exception: e,
      },
    )
  end

  if status == 400
    code = "BAD_REQUEST"
    message = "Bad request"
    details = { body: result }

    if result.is_a?(Array) && result.length == 3 && result[0].is_a?(String) && result[1].is_a?(String)
      code = result[0]
      message = result[1]
      details = result[2]
    end

    raise WebFunction::BadRequestError.new(message, code: code, details: details)
  end

  result
end

.step(url, bearer_auth: nil, args: {}) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/web_function/endpoint.rb', line 77

def step(url, bearer_auth: nil, args: {})
  headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
    "User-Agent": "webfunction/#{WebFunction::VERSION}",
  }

  if args.nil?
    args = {}
  end

  if bearer_auth
    headers["Authorization"] = "Bearer #{bearer_auth}"
  end

  {
    url: url,
    headers: headers,
    body: args,
  }
end

Instance Method Details

#argumentsObject



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/web_function/endpoint.rb', line 179

def arguments
  unless @endpoint["arguments"].is_a?(Array)
    return []
  end

  @endpoint["arguments"].map do |argument|
    unless argument.is_a?(Hash)
      next
    end

    unless argument["name"]
      next
    end

    Argument.new(argument)
  end
end

#attributesObject



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/web_function/endpoint.rb', line 197

def attributes
  unless @endpoint["attributes"].is_a?(Array)
    return []
  end

  @endpoint["attributes"].map do |attribute|
    unless attribute.is_a?(Hash)
      next
    end

    unless attribute["name"]
      next
    end

    Attribute.new(attribute)
  end
end

#docsObject



175
176
177
# File 'lib/web_function/endpoint.rb', line 175

def docs
  @endpoint["docs"].to_s
end

#errorsObject



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/web_function/endpoint.rb', line 215

def errors
  unless @endpoint["errors"].is_a?(Array)
    return []
  end

  @endpoint["errors"].map do |error|
    unless error.is_a?(Hash)
      next
    end

    unless error["code"]
      next
    end

    DocumentedError.new(error)
  end
end

#flagsObject



167
168
169
# File 'lib/web_function/endpoint.rb', line 167

def flags
  [*@endpoint["flags"]].map { |flag| flag.to_s }
end

#groupObject



171
172
173
# File 'lib/web_function/endpoint.rb', line 171

def group
  @endpoint["group"]
end

#hintsObject



163
164
165
# File 'lib/web_function/endpoint.rb', line 163

def hints
  [*@endpoint["hints"]].map { |hint| hint.to_s }
end

#nameObject



155
156
157
# File 'lib/web_function/endpoint.rb', line 155

def name
  @endpoint["name"]
end

#returnsObject



159
160
161
# File 'lib/web_function/endpoint.rb', line 159

def returns
  [*@endpoint["returns"]].map { |type| type.to_s }
end