Mengapa tidak menggunakan SQL daripada GraphQL?

20

Baru-baru ini saya belajar tentang GraphQL yang mengklaim lebih unggul dari RESTful. Namun, saya mulai bertanya-tanya mengapa kita tidak meletakkan pernyataan SQL ke dalam permintaan HTTP GET.

Sebagai contoh, di GraphQL saya akan menulis

{
  Movie(id: "cixos5gtq0ogi0126tvekxo27") {
    id
    title
    actors {
      name
    }
  }
}

Yang tidak jauh lebih sederhana daripada rekan SQL-nya

SELECT id, title FROM movies WHERE id = cixos5gtq0ogi0126tvekxo27;
SELECT actors.name FROM actors, actors_movies WHERE actors.id == movies.actor_id AND movie.id == cixos5gtq0ogi0126tvekxo27;

Mungkin kita dapat menyandikan URL kueri dan mengirim ke server

GET endpoint?q=SELECT%20id%2C%20title%20FROM%20movies%20WHERE%20id%20%3D%20cixos5gtq0ogi0126tvekxo27%3B%0ASELECT%20actors.name%20FROM%20actors%2C%20actors_movies%20WHERE%20actors.id%20%3D%3D%20movies.actor_id%20AND%20movie.id%20%3D%3D%20cixos5gtq0ogi0126tvekxo27%3B HTTP/1.1

Ya, URL kueri bisa terlalu panjang, tetapi Anda bisa memasukkannya ke dalam tubuh permintaan POST jika Anda tidak peduli dengan kepatuhan REST. (Omong-omong, saya pikir HTTP RFC perlu direvisi agar REST masuk akal: membatasi panjang string query mencampur implementasi dengan spesifikasi di awal)

Mengeluarkan SQL secara langsung dari klien juga memiliki kelebihan

  1. Tidak ada kode / pustaka sisi server yang diperlukan untuk mengurai GraphQL, mengurangi waktu pengembangan.
  2. Tidak diperlukan overhead sisi server untuk mem-parsing GraphQL, mengurangi runtime.
  3. Pernyataan SQL jauh lebih fleksibel daripada GraphQL karena (dalam kebanyakan kasus) yang terakhir akan mengurangi menjadi SQL.
  4. Semua orang tahu SQL.

Jadi, apa kelebihan GraphQL dibandingkan SQL?

nalzok
sumber
41
Tabel Bobby Kecil.
Philip Kendall
1
1. Saya masih dapat melakukan Anda dengan pertanyaan SQL yang rumit dan sewenang-wenang. 2. Tidak ada kemungkinan aktor jahat akan mendapatkan kunci yang valid ...
Philip Kendall
3
@ PhilipKendall Anda benar, tetapi menggunakan GraphQL (atau REST atau apa pun) tidak menyelesaikan masalah ini juga, kan?
nalzok
7
@nalzok: SQL is Turing-complete, yang berarti tidak mungkin untuk memvalidasi secara statis.
Jörg W Mittag
3
Ini sangat sederhana untuk memahami mengapa itu ide yang buruk. Terapkan sendiri. Pada titik tertentu, Anda akan menyadari bahwa Anda menginvestasikan waktu sebagian besar dalam 1 hal: keamanan. Tidak terlalu lama Anda akan merasa agak kesal karena Anda menerapkan TOAD caped. Kemudian Anda akan menyadari betapa sulitnya memetakan baris di seluruh sistem dan Anda akan mencoba untuk menemukan kembali roda ORM di kedua sisi: klien dan server. Pada saat Anda menyerah, PM Anda akan meminta laporan: bagaimana layanan pengguna ? Apakah sudah selesai? "...
Laiv

Jawaban:

30

Pada dasarnya abstraksi.

SQL mengharuskan klien Anda untuk mengetahui struktur basis data Anda yang sebenarnya, yang tidak bagus. Selain itu, menganalisis SQL untuk melakukan operasi khusus berdasarkan nilai yang dikirim sebagai input adalah hal yang sangat sulit untuk dilakukan. Ada seluruh perangkat lunak yang cukup banyak hanya bertanggung jawab untuk itu. Apakah kamu tahu apa itu? Jika Anda sudah menebak databasenya, Anda benar.

Berkat tidak mengekspos SQL secara langsung, Anda tidak membatasi konsumen API dengan representasi internal dari database Anda. Anda dengan mudah mengekspos hanya apa yang ingin Anda ungkapkan.

Dan karena klien API hanya bergantung pada abstraksi, Anda bebas untuk memiliki sebanyak mungkin lapisan antara input API dan database aktual (keamanan, caching, memuat data dari banyak basis data dengan satu permintaan, ...).

Untuk layanan publik, mengekspos database secara langsung hampir tidak pernah merupakan pendekatan yang tepat. Namun, jika Anda memiliki beberapa sistem internal, tentu saja, pendekatan Anda mungkin masuk akal, tetapi bahkan mungkin lebih mudah untuk terhubung ke database aplikasi A langsung dari Aplikasi B dengan memberikan kredensial database ke Aplikasi B, daripada mencoba untuk muncul. dengan antarmuka HTTP khusus untuk bahasa SQL database.


Mengapa saya tidak bisa membandingkan URL (atau kueri SQL) dengan kunci di Redis sebelum melakukan kueri aktual pada RDBMS?

Karena itu tidak mudah. Bahkan jika seseorang menggunakan kueri yang sangat sederhana, seperti:

SELECT st.id, jt.name
FROM some_table st
INNER JOIN join_table jt ON jt.some_table_id = st.id
WHERE st.name = 'hello
world' AND st.type = 'STANDARD'

bagaimana Anda memastikan hasilnya di-cache dengan benar? Kueri ini termasuk baris baru, tetapi seseorang bisa juga menulis kueri dengan cara berikut:

SELECT st.id, jt.name FROM some_table st INNER JOIN join_table jt ON jt.some_table_id = st.id WHERE st.name = 'hello
world' AND st.type = 'STANDARD'

dan itu seharusnya masih di-cache dengan cara yang sama seperti yang di atas. Saya secara khusus menyertakan di mana pencarian string berisi baris baru, jadi cukup menemukan ujung baris dan menggantinya dengan spasi tidak akan berfungsi di sini, mem-parsing permintaan dengan benar akan jauh lebih rumit.

Dan bahkan jika Anda memperbaikinya, kueri lain dapat mengubah urutan kondisi dan kueri akan terlihat seperti ini:

SELECT st.id, jt.name
FROM some_table st
INNER JOIN join_table jt ON jt.some_table_id = st.id
WHERE st.type = 'STANDARD' AND st.name = 'hello
world'

dan permintaan lain dapat berisi WHEREargumen redundan , seperti ini:

SELECT st.id, jt.name
FROM some_table st
INNER JOIN join_table jt ON jt.some_table_id = st.id
WHERE st.type = 'STANDARD' AND st.name = 'hello
world' AND st.stype = 'STANDARD'

Semua pertanyaan itu masih seharusnya mengembalikan hasil yang sama, harus di-cache dengan cara yang sama. Tetapi menangani semua opsi yang mungkin hampir tidak mungkin. Itu sebabnya Anda tidak bisa membandingkan URL dengan kunci di Redis.

Andy
sumber
Ini jawaban yang bagus, tetapi silakan lihat pembaruan.
nalzok
19

Secara teori tidak ada alasan Anda tidak dapat mengekspos antarmuka SQL seperti ini.

Dalam praktiknya SQL terlalu kuat untuk dibatasi secara efektif pada cakupan keamanan yang ingin Anda paparkan.

Bahkan jika Anda hanya mengizinkan akses baca, kueri yang buruk masih dapat menyimpan sumber daya.

Bahasa lain seperti graphQL dirancang untuk diekspos. Mereka hanya memberi pengguna opsi filter pada apa yang sudah bisa mereka lihat.

Manfaat menggunakan bahasa-bahasa ini adalah bahwa mereka telah melalui semua hal yang Anda ingin hentikan yang dilakukan pengguna dalam SQL dan menghapusnya.

Ewan
sumber
2
Terima kasih atas jawabannya, tetapi bisakah Anda menjelaskan bagaimana GraphQL memecahkan masalah pengeringan sumber daya? Permintaan GraphQL yang nakal masih dapat mengatakan "ceritakan semuanya tentang setiap film dan aktor mereka", menghasilkan grafik yang sangat besar, dan melelahkan DBMS dan jaringan saya.
nalzok
Tetapi saya dapat menulis kueri SQL rekursif yang akan mengunci meja Anda dan mencegah pengguna lain menjalankan kueri sama sekali
Ewan
4
masalahnya bukan membatasi akses ke tabel, atau menghapus, tetapi kompleksitas geser SQL. Anda akan mengizinkan pembuatan tabel temp? bagaimana dengan mengeksekusi CLI? loop? transaksi? sub memilih? kursor? bagaimana Anda membedakan kapan penggunaan hal-hal ini dapat diterima dan ketika 'buruk'
Ewan
2

Seperti yang telah disebutkan orang lain, mengekspos SQL secara langsung dalam api adalah pilihan yang sangat buruk. GraphQL, terlepas dari namanya, bukan abstraksi untuk SQL, tetapi untuk penyimpanan data apa pun atau bahkan layanan lainnya.

Jika Anda mencari abstraksi yang lebih dekat ke SQL, Anda mungkin ingin melihat odata (jika Anda bekerja di. Backends NET, meskipun mungkin ada implementasi lain).

jannikb
sumber
0

jika Anda ingin mengekspos SQL seperti GraphQL, Anda akan memerlukan sesuatu seperti GraphQL, karena Anda perlu menyembunyikan informasi penting dan memilih apa yang ingin Anda perlihatkan di API, ini untuk keamanan.

GraphQl dan SQL adalah hal yang berbeda, SQL adalah bahasa untuk meminta DataBase dan GraphQL hanya untuk mengelola data dari API, di API Anda perlu membuat skema Anda untuk ditampilkan dan meminta untuk mengelolanya, dll.

di API apa pun Anda perlu membuat hal-hal itu hanya untuk keamanan, tetapi jika Anda menginginkan sesuatu yang akses data gratis mungkin itu akan berhasil, Anda tahu begitu banyak alternatif di dunia perangkat lunak

Lubang hitam
sumber