Faraday: ์˜ˆ์•ฝ๋œ ๋ฌธ์ž๊ฐ€ ํฌํ•จ๋œ ๊ฒฝ์šฐ URI ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2020๋…„ 12์›” 04์ผ  ยท  3์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: lostisland/faraday

๊ธฐ๋ณธ ์ •๋ณด

  • ํŒจ๋Ÿฌ๋ฐ์ด ๋ฒ„์ „: 1.1.0
  • ๋ฃจ๋น„ ๋ฒ„์ „: 2.7.1

๋ฌธ์ œ ์„ค๋ช…

๋‚ด๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์„œ๋น„์Šค ์ œ๊ณต์—…์ฒด ์ค‘ ํ•˜๋‚˜๋Š” https://service.com/service:search ์™€ ๊ฐ™์€ URL์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํŒจ๋Ÿฌ๋ฐ์ด๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

class Provider::Client
 ...
 delegate :post, :patch, :delete, :put, to: :client

 def client
  Faraday.new(url: 'https://service.com/') do |faraday|
    faraday.headers = headers.merge(content_type: content_type)
    faraday.response(:json, content_type: CONTENT_TYPE)
    faraday.basic_auth(USER, PASSWORD)
    faraday.adapter(Faraday.default_adapter)
  end
 end
end

๊ทธ๋ฆฌ๊ณ  ๋‚ด๊ฐ€ ๊ทธ๊ฒƒ์„ ํ˜ธ์ถœ ํ•  ๋•Œ

data = Provider::Client.post(
  "service:search?limit=#{LIMIT}&offset=#{offset}", search_params
)

ํ•˜์ง€๋งŒ ๋ฌธ์ œ์˜ URL๋กœ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

URI::InvalidURIError: query conflicts with opaque
from /Users/luiz/.rbenv/versions/2.7.1/lib/ruby/2.7.0/uri/generic.rb:832:in `query='

๊ธฐ๋ณธ ์–ด๋Œ‘ํ„ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— net/http ์–ด๋Œ‘ํ„ฐ์™€ ๊ด€๋ จ๋œ ๊ฒƒ์œผ๋กœ ๊ฐ€์ •ํ•˜์—ฌ ์ˆ˜๋™์œผ๋กœ ๋™์ผํ•œ ํ˜ธ์ถœ์„ ์ˆ˜ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

require "uri"
require "net/http"

url = URI("https://service.com/service:search?limit=50&offset=400")

https = Net::HTTP.new(url.host, url.port);
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Accept"] = "custom_header"
request["Authorization"] = "Basic xxx="
request["Content-Type"] = "application/json"
request.body = "long_json"
response = https.request(request)

puts response.read_body

๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์€ ์‹ค์ œ๋กœ ์ž‘๋™ํ•˜๋ฏ€๋กœ Faraday์˜ ๋ฌด์–ธ๊ฐ€๊ฐ€ net/http์™€ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ด URL์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

bug good first issue

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@luizkowalski ์™„๋ฒฝ, ๋„ค, ๊ทธ๊ฒŒ ์ •ํ™•ํžˆ ์ œ๊ฐ€ ์˜๋ฏธํ•œ ๋ฐ”์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ /๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†๋Š” ๊ธฐ์ค€์— ์ƒ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฏ€๋กœ ๋ชจ๋“  ๊ฒฝ์šฐ์— ์ž‘๋™ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

ํŒจ๋Ÿฌ๋ฐ์ด๋Š” ์ œ๊ณต๋œ URL์ด / ๋กœ ์‹œ์ž‘ํ•˜๊ณ  ๊ธฐ๋ณธ์— ์ œ๊ณต๋œ ๊ฒฝ๋กœ๋ฅผ ์ œ๊ฑฐํ•œ ๊ฒฝ์šฐ ์ ˆ๋Œ€ URL์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.
์ด๋ฏธ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ฐพ์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹คํ–‰์ด์ง€๋งŒ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ๋” ์ด์ƒ ํ•„์š”ํ•˜์ง€ ์•Š๋„๋ก ์—ฌ์ „ํžˆ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ˆ˜์ •๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  3 ๋Œ“๊ธ€

์•ˆ๋…•ํ•˜์„ธ์š” @luizkowalski , ์˜ˆ์™ธ๋Š” URI ์—์„œ ๋ฐœ์ƒํ•˜๋ฉฐ query= ๋ฉ”์„œ๋“œ์˜ ์ฒซ ๋ฒˆ์งธ ์ค„์—์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

def query=(v)
  return <strong i="9">@query</strong> = nil unless v
  raise InvalidURIError, "query conflicts with opaque" if <strong i="10">@opaque</strong>
  ...
end

ํŒจ๋Ÿฌ๋ฐ์ด๋Š” ์š”์ฒญ ๋ถ„ํ• ํ•˜์—ฌ URL๊ณผ ๋ช‡ ๊ฐ€์ง€ ์ผ๋ฐ˜์ ์ธ ๋ณ€ํ™˜ ๋„์›€์œผ๋กœ ์žฌ๊ฒฐํ•ฉ์— ์ผ๋ถ€ ๋‚ด๋ถ€ ๋งˆ๋ฒ•์„ ์ˆ˜ํ–‰ํ•˜๊ณ , ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ์–ด๋–ค ์‹œ์ ์—์„œ ์ถ”์ • @opaque ์˜ ์กด์žฌ ๋•๋ถ„์— ์„ค์ • ๋  : URL์—
๋‹ค์Œ ์ค„๊นŒ์ง€ ๋ฌธ์ œ๋ฅผ ์ถ”์ ํ–ˆ์Šต๋‹ˆ๋‹ค. https://github.com/lostisland/faraday/blob/c26df87b8653db4f270e3bcdc7a15bcdd2dd5cae/lib/faraday/connection.rb#L525
์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด base ๋Š” #<URI::HTTPS https://service.com/> ์ด๊ณ  url ๋Š” service:search?limit=50&offset=400 ์ž…๋‹ˆ๋‹ค.
์ด์ œ ํฅ๋ฏธ๋กญ๊ฒŒ์˜ ๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ ๋ณ€์ˆ˜ ๊ฒฝ์šฐ + URI์— ๋Œ€ํ•œ ๋ฐฉ๋ฒ•์ด ํฌํ•จ ๋œ : ๊ฒฐ๊ณผ๊ฐ€ ๋งค์šฐ ์˜ˆ๊ธฐ์น˜ ์•Š์€์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค!

2.7.1 > url
 => "service:search?limit=50&offset=400" 
2.7.1 > base
 => #<URI::HTTPS https://service.com/> 
2.7.1 > base + url
 => #<URI::Generic service:search?limit=50&offset=400>

์–ด๋–ค ์ด์œ ๋กœ base ๋Š” ์ œ๊ฑฐ๋˜๊ณ  url๋งŒ ๋‚จ์Šต๋‹ˆ๋‹ค.
์ด ๊ฒฝ์šฐ ์ˆ˜์ •์€ ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. URL ์•ž์— / ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

data = Provider::Client.post(
  "/service:search?limit=#{LIMIT}&offset=#{offset}", search_params
)

๊ทธ๋Ÿฌ๋‚˜ / ์‹œ์ž‘ํ•  ์ˆ˜ ์—†๋Š” base ์ƒ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ชจ๋“  ๊ฒฝ์šฐ์— ์ž‘๋™ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.
/ ์•ž์— ์ถ”๊ฐ€ํ•˜์—ฌ ์‹œ๋„ํ•ด ๋ณด๊ณ  ์ž‘๋™ํ•˜๋Š”์ง€ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค. ํ•˜์ง€๋งŒ ์ด ๋ฌธ์ œ๋ฅผ ์—ด์–ด๋‘๊ณ  ์‚ดํŽด๋ณด๊ณ  Faraday์—์„œ ํ•ด๋‹น ์ฝ”๋“œ ์ค„์„ ์ˆ˜์ •ํ•˜์—ฌ ์ด ๊ฒฝ์šฐ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
์ง์ ‘ ์‹œ๋„ํ•ด๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด ๊ธฐ๊บผ์ด PR์„ ๊ฒ€ํ† ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค ๐Ÿ˜ƒ

@iMacTia ์ด์ œ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ URL์€ https://service.com/api ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ถ”๊ฐ€ํ•˜๋ฉด / ์— service:search I๊ฐ€ ์žˆ๋‹ค๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค ๋ˆˆ์น˜ /api ๋‚ด๊ฐ€ ์ถ”๊ฐ€ํ•˜๋„๋ก ๊ธฐ๋ณธ URL์—์„œ ์‚ฌ๋ผ์กŒ๋‹ค /api/service:search ํ•˜๊ณ  ์ง€๊ธˆ์€์˜ ๋ฒŒ๊ธˆ์„

@luizkowalski ์™„๋ฒฝ, ๋„ค, ๊ทธ๊ฒŒ ์ •ํ™•ํžˆ ์ œ๊ฐ€ ์˜๋ฏธํ•œ ๋ฐ”์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ /๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†๋Š” ๊ธฐ์ค€์— ์ƒ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฏ€๋กœ ๋ชจ๋“  ๊ฒฝ์šฐ์— ์ž‘๋™ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

ํŒจ๋Ÿฌ๋ฐ์ด๋Š” ์ œ๊ณต๋œ URL์ด / ๋กœ ์‹œ์ž‘ํ•˜๊ณ  ๊ธฐ๋ณธ์— ์ œ๊ณต๋œ ๊ฒฝ๋กœ๋ฅผ ์ œ๊ฑฐํ•œ ๊ฒฝ์šฐ ์ ˆ๋Œ€ URL์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.
์ด๋ฏธ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ฐพ์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹คํ–‰์ด์ง€๋งŒ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ๋” ์ด์ƒ ํ•„์š”ํ•˜์ง€ ์•Š๋„๋ก ์—ฌ์ „ํžˆ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ˆ˜์ •๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰