API kursów walut dla Ruby on Rails
API kursów walut dla Ruby on Rails. Praktyczny poradnik z kodem, pamięcią podręczną i metadanymi świeżości.
Wdrażaj po stronie serwera bez ujawniania danych dostępowych i zachowuj źródło oraz czas obserwacji.
Najważniejsze punkty
Klucz API przechowuj na serwerze. Waliduj kody walut i kwoty. Buforuj poprawne odpowiedzi. Pokazuj źródło i czas obserwacji. Krok 1
Przykład koducopy
require "net/http"
require "json"
class ExchangeRateClient
Error = Class.new(StandardError)
def convert(from:, to:, amount:)
from = from.to_s.upcase
to = to.to_s.upcase
raise Error, "invalid currency code" unless [from, to].all? { |code| code.match?(/A[A-Z]{3}z/) }
key = ["fx-convert", from, to, amount.to_d.to_s("F")]
Rails.cache.fetch(key, expires_in: 60.seconds) do
uri = URI("https://api.exchangerate.dev/v1/convert/#{from}/#{to}/#{amount}")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("EXCHANGERATE_API_KEY")}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true,
open_timeout: 2, read_timeout: 5) { |http| http.request(request) }
raise Error, "exchange-rate API returned #{response.code}" unless response.is_a?(Net::HTTPSuccess)
JSON.parse(response.body)
end
rescue Net::OpenTimeout, Net::ReadTimeout => error
raise Error, "exchange-rate API timed out: #{error.class}"
end
endKrok 2
Przykład koducopy
class ConversionsController < ApplicationController
def show
amount = BigDecimal(params.require(:amount))
result = ExchangeRateClient.new.convert(
from: params.require(:from).upcase,
to: params.require(:to).upcase,
amount: amount
)
render json: result.slice("from", "to", "amount", "rate", "converted",
"source", "market_session", "data_updated_at")
rescue ExchangeRateClient::Error, ArgumentError => error
render json: { error: error.message }, status: :bad_gateway
end
endKrok 3
Uruchamiaj na serwerze, waliduj dane wejściowe i zachowuj metadane odpowiedzi.
Krok 4
Uruchamiaj na serwerze, waliduj dane wejściowe i zachowuj metadane odpowiedzi.
Poradnik
Kursy są orientacyjne i nie są cenami rozliczeniowymi.