Saya mengikuti petunjuk ini untuk mengirimkan kueri SPARQL, lebih memilih metode POST sebagai kueri mungkin cukup lama. Tetapi tampaknya gagal meskipun GET berfungsi - adakah cara untuk membuat kueri POST berfungsi?

sparql = <<END
SELECT ?item ?itemLabel 
WHERE 
{
    ?item wdt:P31 wd:Q146.
    SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
END

# Fails with 405 Not writable
resp = Excon.post('https://query.wikidata.org/sparql', body: "query=#{URI::encode(sparql)}")
puts resp.status, resp.body

# Works with 200
resp = Excon.get("https://query.wikidata.org/sparql?query=#{URI::encode(sparql)}")
puts resp.status, resp.body

Saya sudah mencoba mengirim "Content-Type" => "application/x-www-form-urlencoded" juga, tetapi tidak berhasil.

4
mahemoff 21 September 2019, 17:46

1 menjawab

Jawaban Terbaik

Terima kasih kepada komentator di atas untuk menunjukkan contoh kerja. Saya melakukan beberapa pemeriksaan lebih lanjut berdasarkan semua kombinasi yang jelas, seperti di bawah ini.

Singkatnya:

  • Gunakan GET jika pendek dan kemungkinan akan digunakan kembali (karena kueri GET di-cache)
  • Pastikan Anda mengirim header user-agent dan perhatikan bahwa beberapa pustaka tidak akan menyertakannya secara default (jika tidak, ia akan mengembalikan 403) yang tidak dapat dijelaskan
  • Untuk POST, yang terbaik dan paling sederhana (menurut saya) adalah mengirim kueri SPARQL sebagai seluruh isi dengan "tipe konten" sebagai "aplikasi/sparql-query", tidak diperlukan penyandian kueri di sini. Anda juga dapat menggunakan sintaks formulir dengan "tipe konten" sebagai "aplikasi/x-www-form-urlencoded" dan memastikan kueri dikodekan.
require 'excon'

# any arbitrary query   
sparql = 'SELECT ?item ?itemLabel WHERE { ?item wdt:P31 wd:Q146.  SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } }'

# SUCCESS!
resp = Excon.get("https://query.wikidata.org/sparql?query=#{URI::encode(sparql)}")
puts "GET", resp.status, resp.body[0,100], "\n"

# FAIL! 403 (need user agent)
headers = { "Content-Type" => "application/sparql-query" }
resp= Excon.post('https://query.wikidata.org/sparql', body: sparql, headers: headers)
puts "POST sparql-query", resp.status, resp.body[0,100], "\n"

# SUCCESS!
headers = { "Content-Type" => "application/sparql-query", "User-Agent" => "Ruby 2.6.4" }
resp= Excon.post('https://query.wikidata.org/sparql', body: sparql, headers: headers)
puts "POST sparql-query with user-agent", resp.status, resp.body[0,100], "\n"

# FAIL! 403 (need user agent)
headers = { "Content-Type" => "application/x-www-form-urlencoded" }
resp = Excon.post('https://query.wikidata.org/sparql', body: "query=#{URI::encode(sparql)}", headers: headers)
puts "POST form", resp.status, resp.body[0,100], "\n"

# SUCCESS!
headers = { "Content-Type" => "application/x-www-form-urlencoded", "User-Agent" => "Ruby 2.6.4" }
resp = Excon.post('https://query.wikidata.org/sparql', body: "query=#{URI::encode(sparql)}", headers: headers)
puts "POST form with user-agent", resp.status, resp.body[0,100], "\n"

# FAIL! 405 (need encoding)
resp = Excon.post('https://query.wikidata.org/sparql', body: "query=#{URI::encode(sparql)}")
puts "POST plain", resp.status, resp.body[0,100], "\n"

# FAIL! 405 (need encoding)
headers = { "User-Agent" => "Ruby 2.6.4" }
resp = Excon.post('https://query.wikidata.org/sparql', body: "query=#{URI::encode(sparql)}", headers: headers)
puts "POST plain with user-agent", resp.status, resp.body[0,100], "\n"

Info selengkapnya

6
Stanislav Kralin 23 September 2019, 15:46