Class: Crystil::API::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/crystil/api/base.rb,
sig/crystil/api/base.rbs

Overview

Base HTTP client for Crystil API

Direct Known Subclasses

Invocation, Sentinel, Workflow, Workflows

Instance Method Summary collapse

Constructor Details

#initialize(api_url, api_key, timeout) ⇒ Base

Returns a new instance of Base.

Parameters:

  • api_url (String)
  • api_key (String)
  • timeout (Numeric)


11
12
13
14
15
16
# File 'lib/crystil/api/base.rb', line 11

def initialize(api_url, api_key, timeout)
  @original_api_url = api_url
  @api_url = "#{api_url}/v1/-"
  @api_key = api_key
  @timeout = timeout
end

Instance Method Details

#build_request(method, uri, body) ⇒ Net::HTTP::Delete, ...

Parameters:

  • method (Symbol)
  • uri (URI::Generic)
  • body (Hash[Symbol, untyped], nil)

Returns:

  • (Net::HTTP::Delete, Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Put)


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/crystil/api/base.rb', line 61

def build_request(method, uri, body)
  request_class = case method
                  when :get then Net::HTTP::Get
                  when :post then Net::HTTP::Post
                  when :put then Net::HTTP::Put
                  when :delete then Net::HTTP::Delete
                  else raise ArgumentError, "Unsupported HTTP method: #{method}"
                  end

  request = request_class.new(uri.path.empty? ? "/" : uri.path)
  request["Authorization"] = "Bearer #{@api_key}"
  request["Content-Type"] = "application/json"
  request["User-Agent"] = "crystil-ruby/#{Crystil::VERSION}"

  request.body = JSON.generate(body) if body && %i[post put].include?(method)

  request
end

#delete(path) ⇒ Object

Parameters:

  • path (String)

Returns:

  • (Object)


32
33
34
# File 'lib/crystil/api/base.rb', line 32

def delete(path)
  request(:delete, path)
end

#get(path) ⇒ Object

Parameters:

  • path (String)

Returns:

  • (Object)


20
21
22
# File 'lib/crystil/api/base.rb', line 20

def get(path)
  request(:get, path)
end

#handle_response(response) ⇒ Object

Parameters:

  • response (Net::HTTPResponse)

Returns:

  • (Object)


80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/crystil/api/base.rb', line 80

def handle_response(response)
  case response
  when Net::HTTPSuccess
    parse_json_response(response.body)
  when Net::HTTPNoContent
    {}
  else
    raise APIError.new(
      "API request failed: #{response.code} #{response.message}",
      status_code: response.code.to_i,
      response_body: response.body
    )
  end
end

#parse_json_response(body) ⇒ Object

Parameters:

  • body (String, nil)

Returns:

  • (Object)


95
96
97
98
99
100
101
# File 'lib/crystil/api/base.rb', line 95

def parse_json_response(body)
  return {} if body.nil? || body.empty?

  JSON.parse(body)
rescue JSON::ParserError => e
  raise APIError, "Failed to parse JSON response: #{e.message}"
end

#post(path, body = nil) ⇒ Object

Parameters:

  • path (String)
  • body (Hash[Symbol, untyped], nil) (defaults to: nil)

Returns:

  • (Object)


24
25
26
# File 'lib/crystil/api/base.rb', line 24

def post(path, body = nil)
  request(:post, path, body)
end

#put(path, body = nil) ⇒ Object

Parameters:

  • path (String)
  • body (Hash[Symbol, untyped], nil) (defaults to: nil)

Returns:

  • (Object)


28
29
30
# File 'lib/crystil/api/base.rb', line 28

def put(path, body = nil)
  request(:put, path, body)
end

#request(method, path, body = nil) ⇒ Object

Parameters:

  • method (Symbol)
  • path (String)
  • body (Hash[Symbol, untyped], nil) (defaults to: nil)

Returns:

  • (Object)


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/crystil/api/base.rb', line 38

def request(method, path, body = nil)
  # Construct full URL - path should start with /
  full_url = "#{@api_url}#{path}"
  uri = URI.parse(full_url)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = uri.scheme == "https"

  # Configure SSL to use system certificates
  if http.use_ssl?
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
    http.cert_store = OpenSSL::X509::Store.new
    http.cert_store.set_default_paths
  end

  http.open_timeout = @timeout
  http.read_timeout = @timeout

  request = build_request(method, uri, body)
  response = http.request(request)

  handle_response(response)
end