Detail GraphQL: Apa, Bagaimana, dan Mengapa

GraphQL sekarang, tanpa berlebihan, ini adalah puncak terakhir dari IT-mode. Dan jika Anda belum tahu teknologi apa itu, bagaimana menggunakannya, dan mengapa itu mungkin berguna bagi Anda, maka artikel yang kami terbitkan hari ini ditulis untuk Anda. Di sini kita akan membahas dasar-dasar GraphQL menggunakan contoh implementasi skema data untuk API perusahaan popcorn. Secara khusus, mari kita bicara tentang tipe data, kueri, dan mutasi.



Apa itu GraphQL?


GraphQL adalah bahasa permintaan yang digunakan oleh aplikasi klien untuk bekerja dengan data. GraphQL dikaitkan dengan konsep seperti "skema" - inilah yang memungkinkan Anda untuk mengatur pembuatan, membaca, memperbarui, dan menghapus data dalam aplikasi Anda (yaitu, kami memiliki empat fungsi dasar yang digunakan saat bekerja dengan gudang data, yang biasanya disebut oleh akronim CRUD - buat, baca, perbarui, hapus).

Dikatakan di atas bahwa GraphQL digunakan untuk bekerja dengan data dalam "aplikasi Anda", dan bukan "dalam database Anda". Faktanya adalah bahwa GraphQL adalah sistem yang tidak tergantung pada sumber data, artinya, tidak masalah di mana ia diatur untuk mengatur pekerjaannya.

Jika Anda melihat, tanpa mengetahui apa-apa tentang GraphQL, atas nama teknologi ini, mungkin kita dihadapkan pada sesuatu yang sangat rumit dan membingungkan. Nama teknologinya bertuliskan "Grafik". Apakah ini berarti bahwa untuk menguasainya, Anda harus belajar bekerja dengan basis data grafik? Dan fakta bahwa namanya mengandung "QL" (yang dapat berarti "bahasa query", yaitu, "bahasa query"), apakah itu berarti bahwa mereka yang ingin menggunakan GraphQL harus mempelajari bahasa pemrograman yang sama sekali baru?

Ketakutan ini tidak sepenuhnya dibenarkan. Untuk meyakinkan Anda - ini adalah kebenaran yang kejam tentang teknologi ini: itu hanya dihiasi permintaan GET atau POST . Sementara GraphQL, secara umum, memperkenalkan beberapa konsep baru yang terkait dengan organisasi data dan interaksi dengannya, mekanisme internal teknologi ini bergantung pada permintaan HTTP lama yang baik.

Memikirkan Kembali Teknologi REST


Fleksibilitas adalah apa yang membedakan teknologi GraphQL dari teknologi REST yang terkenal. Saat menggunakan REST, jika semuanya dilakukan dengan benar, titik akhir biasanya dibuat dengan mempertimbangkan karakteristik sumber daya atau tipe data aplikasi tertentu.

Misalnya, saat melakukan permintaan GET ke rasa titik akhir /api/v1/flavors diharapkan akan mengirimkan respons yang terlihat seperti ini:

 [ {  "id": 1,   "name": "The Lazy Person's Movie Theater",   "description": "That elusive flavor that you begrudgingly carted yourself to the theater for, now in the comfort of your own home, you slob!" }, {   "id": 2,   "name": "What's Wrong With You Caramel",   "description": "You're a crazy person that likes sweet popcorn. Congratulations." }, {   "id": 3,   "name": "Gnarly Chili Lime",   "description": "The kind of popcorn you make when you need a good smack in the face."} ] 

Tidak ada yang salah dengan jawaban ini, tetapi mari kita pikirkan tentang antarmuka pengguna, atau lebih tepatnya, bagaimana kami bermaksud untuk mengkonsumsi data ini.

Jika kami ingin menampilkan daftar sederhana di antarmuka yang hanya berisi nama-nama jenis popcorn yang tersedia (dan tidak ada yang lain), maka daftar ini mungkin terlihat seperti yang ditunjukkan di bawah ini.


Daftar Jenis Popcorn

Dapat dilihat bahwa di sini kita berada dalam situasi yang sulit. Kami mungkin memutuskan untuk tidak menggunakan bidang description , tetapi apakah kami akan duduk dan berpura-pura bahwa kami tidak mengirimkan bidang ini ke klien? Apa lagi yang bisa kita lakukan? Dan ketika, setelah beberapa bulan, mereka akan bertanya kepada kami mengapa aplikasi ini sangat lambat bagi pengguna, kami hanya perlu membiarkan orang itu dan tidak lagi bertemu dengan manajemen perusahaan tempat kami membuat aplikasi ini.

Faktanya, fakta bahwa server mengirim data yang tidak perlu sebagai tanggapan atas permintaan klien bukan sepenuhnya kesalahan kami. REST adalah mekanisme akuisisi data yang dapat dibandingkan dengan restoran di mana pelayan bertanya kepada pengunjung: "Apa yang Anda inginkan?", Dan, tidak terlalu memperhatikan keinginannya, ia mengatakan kepadanya: "Aku akan membawakan apa yang kami miliki" .

Jika kita membuang lelucon, maka dalam aplikasi nyata ini dapat menyebabkan situasi masalah. Misalnya, kita dapat menampilkan berbagai informasi tambahan tentang setiap jenis popcorn, seperti informasi harga, informasi tentang produsen atau informasi nutrisi (“Popcorn Vegan!”). Pada saat yang sama, titik akhir REST yang tidak fleksibel membuatnya sangat sulit untuk mendapatkan data spesifik tentang jenis popcorn tertentu, yang mengarah pada beban yang terlalu tinggi pada sistem dan pada kenyataan bahwa solusi yang dihasilkan jauh dari yang bisa dibanggakan oleh pengembang.

Bagaimana Teknologi GraphQL Meningkatkan Teknologi REST Digunakan Untuk Apa


Analisis dangkal dari situasi yang dijelaskan di atas mungkin tampak bahwa kita hanya masalah kecil. "Apa yang salah dengan mengirim data yang tidak perlu ke klien?" Untuk memahami sejauh mana "data yang tidak perlu" bisa menjadi masalah besar, ingatlah bahwa GraphQL dikembangkan oleh Facebook. Perusahaan ini harus melayani jutaan permintaan per detik.

Apa artinya ini? Dan fakta bahwa dengan volume seperti itu setiap hal kecil penting.

GraphQL, jika kita melanjutkan analogi dengan restoran, alih-alih “membawa” ke pengunjung “apa adanya”, membawa persis apa yang dipesan pengunjung.

Kita bisa mendapatkan respons dari GraphQL yang berfokus pada konteks di mana data digunakan. Dalam hal ini, kita tidak perlu menambahkan titik akses "satu kali" ke sistem, melakukan banyak permintaan atau menulis struktur bersyarat bertingkat.

Bagaimana cara kerja GraphQL?


Seperti yang telah kami katakan, GraphQL bergantung pada permintaan GET atau POST sederhana untuk mengirimkan data ke klien dan menerimanya dari itu. Jika kami mempertimbangkan ide ini lebih terinci, ternyata ada dua jenis kueri di GraphQL. Tipe pertama termasuk permintaan untuk membaca data, yang dalam terminologi GraphQL hanya disebut kueri dan merujuk ke huruf R (membaca, membaca) dari akronim CRUD. Permintaan jenis kedua adalah permintaan modifikasi data, yang disebut mutasi dalam GraphQL. Mereka berhubungan dengan kotak as roda C, U, dan D dari akronim CRUD, yaitu, mereka menggunakannya untuk membuat, membuat, memperbarui, dan menghapus catatan.

Semua pertanyaan dan mutasi ini dikirim ke URL server GraphQL, yang, misalnya, mungkin terlihat seperti https://myapp.com/graphql , dalam bentuk GET atau permintaan POST . Kami akan berbicara lebih banyak tentang ini di bawah ini.

Permintaan GraphQL


Kueri GraphQL adalah entitas yang mewakili permintaan ke server untuk menerima data tertentu. Misalnya, kami memiliki antarmuka pengguna tertentu yang ingin kami isi dengan data. Untuk data ini, kami beralih ke server, menjalankan permintaan. Saat menggunakan API REST tradisional, permintaan kami berbentuk permintaan GET. Saat bekerja dengan GraphQL, sintaks kueri baru digunakan:

 { flavors {   name } } 

Apakah itu JSON? Atau objek JavaScript? Tidak satu atau yang lain. Seperti yang telah kita katakan, atas nama teknologi GraphQL, dua huruf terakhir, QL, berarti "bahasa query", yaitu, bahasa query. Ini, secara harfiah, bahasa baru untuk menulis permintaan data. Semua ini terdengar seperti deskripsi sesuatu yang agak rumit, tetapi sebenarnya tidak ada yang rumit di sini. Mari kita menganalisis permintaan di atas:

 { //    ,   . } 

Semua permintaan dimulai dengan "permintaan root", dan apa yang Anda butuhkan selama eksekusi permintaan disebut bidang. Untuk menyelamatkan diri dari kebingungan, yang terbaik adalah menyebut entitas ini "bidang kueri dalam skema." Jika nama seperti itu tampaknya tidak dapat dipahami oleh Anda - tunggu sebentar - di bawah ini kami akan berbicara lebih banyak tentang skema tersebut. Di sini kita, dalam permintaan root, meminta bidang flavors .

 { flavors {   //  ,        flavor. } } 

Saat meminta bidang tertentu, kami juga harus menunjukkan bidang bersarang yang harus diterima untuk setiap objek yang menanggapi permintaan (bahkan jika diharapkan hanya satu objek yang akan menanggapi permintaan).

 { flavors {   name } } 

Apa hasilnya? Setelah kami mengirim permintaan seperti itu ke server GraphQL, kami akan mendapatkan jawaban yang rapi seperti berikut:

 { "data": {   "flavors": [     { "name": "The Lazy Person's Movie Theater" },     { "name": "What's Wrong With You Caramel" },     { "name": "Gnarly Chili Lime" }   ] } } 

Harap dicatat bahwa tidak ada yang berlebihan. Untuk membuatnya lebih jelas, berikut ini adalah permintaan lain yang dijalankan untuk mendapatkan data pada halaman lain dari aplikasi:

 { flavors {   id   name   description } } 

Menanggapi permintaan ini, kami mendapatkan yang berikut:

 { "data": {   "flavors": [     { "id": 1, "name": "The Lazy Person's Movie Theater", description: "That elusive flavor that you begrudgingly carted yourself to the theater for, now in the comfort of your own home, you slob!" },     { "id": 2, "name": "What's Wrong With You Caramel", description: "You're a crazy person that likes sweet popcorn. Congratulations." },     { "id": 3, "name": "Gnarly Chili Lime", description: "A friend told me this would taste good. It didn't. It burned my kernels. I haven't had the heart to tell him." }   ] } } 

Seperti yang Anda lihat, GraphQL adalah teknologi yang sangat kuat. Kami beralih ke titik akhir yang sama, dan jawaban atas permintaan tepat sesuai dengan apa yang diperlukan untuk mengisi halaman dari mana permintaan ini dieksekusi.

Jika kita hanya perlu mendapatkan satu objek flavor , maka kita dapat memanfaatkan fakta bahwa GraphQL dapat bekerja dengan argumen:

 { flavors(id: "1") {   id   name   description } } 

Di sini kita secara kaku mengatur pengidentifikasi spesifik ( id ) objek dalam kode, informasi yang kita butuhkan, tetapi dalam kasus seperti itu kita dapat menggunakan pengidentifikasi dinamis:

 query getFlavor($id: ID) { flavors(id: $id) {   id   name   description } } 

Di sini, di baris pertama, kami memberikan nama permintaan (nama dipilih secara sewenang-wenang, getFlavor dapat diganti dengan sesuatu seperti pizza , dan permintaan akan tetap operasional) dan mendeklarasikan variabel yang diharapkan oleh permintaan. Dalam hal ini, diasumsikan bahwa pengidentifikasi ( id ) dari tipe skalar ID akan diteruskan ke permintaan (kita akan berbicara tentang jenis di bawah).

Terlepas dari apakah id statis atau dinamis digunakan saat mengeksekusi permintaan, berikut adalah respons terhadap permintaan serupa:

 { "data": {   "flavors": [     { "id": 1, "name": "The Lazy Person's Movie Theater", description: "That elusive flavor that you begrudgingly carted yourself to the theater for, now in the comfort of your own home, you slob!" }   ] } } 

Seperti yang Anda lihat, semuanya diatur dengan sangat nyaman. Anda mungkin mulai berpikir untuk menggunakan GraphQL di proyek Anda sendiri. Dan, meskipun apa yang telah kita bicarakan terlihat luar biasa, keindahan GraphQL benar-benar memanifestasikan dirinya di mana ia bekerja dengan bidang bersarang. Misalkan dalam skema kami ada bidang lain yang disebut nutrition yang berisi informasi tentang nilai gizi berbagai jenis popcorn:

 { flavors {   id   name   nutrition {     calories     fat     sodium   } } } 

Tampaknya di gudang data kami, setiap objek flavor akan berisi objek nutrition bersarang. Tetapi ini tidak sepenuhnya benar. Menggunakan GraphQL, Anda dapat menggabungkan panggilan ke sumber data yang independen, tetapi terkoneksi dalam satu kueri, yang memungkinkan Anda untuk mendapatkan jawaban yang memberikan kemudahan bekerja dengan data yang disematkan tanpa perlu mendenormalkan basis data:

 { "data": {   "flavors": [     {       "id": 1,       "name": "The Lazy Person's Movie Theater",       "nutrition": {         "calories": 500,         "fat": 12,         "sodium": 1000       }     },     ...   ] } } 

Ini secara signifikan dapat meningkatkan produktivitas programmer dan kecepatan sistem.

Sejauh ini, kami telah berbicara tentang permintaan baca. Bagaimana dengan permintaan pembaruan data? Apakah menggunakan mereka memberi kita kenyamanan yang sama?

Mutasi GraphQL


Sementara GraphQL kueri memuat data, mutasi bertanggung jawab untuk membuat perubahan pada data. Mutasi dapat digunakan dalam bentuk mekanisme RPC (Remote Procedure Call) dasar untuk menyelesaikan berbagai tugas, seperti mengirim data pengguna ke API pihak ketiga.

Saat menjelaskan mutasi, sintaks digunakan yang menyerupai yang kami gunakan saat membuat kueri:

 mutation updateFlavor($id: ID!, $name: String, $description: String) { updateFlavor(id: $id, name: $name, description: $description) {   id   name   description } } 

Di sini kami mendeklarasikan mutasi updateFlavor , menetapkan beberapa variabel - id , name dan description . Bertindak sesuai dengan skema yang sama yang digunakan untuk menggambarkan kueri, kami “menyusun” bidang variabel (mutasi root) menggunakan kata kunci mutation , diikuti dengan nama yang menggambarkan mutasi, dan satu set variabel yang diperlukan untuk membentuk permintaan perubahan data yang sesuai.

Variabel-variabel ini termasuk apa yang kita coba ubah, atau mutasi apa yang ingin kita sebabkan. Harap perhatikan juga bahwa setelah mutasi, kami dapat meminta pengembalian beberapa bidang.

Dalam hal ini, kita perlu mendapatkan, setelah mengubah catatan, bidang id , name dan description . Ini bisa berguna ketika mengembangkan sesuatu seperti antarmuka optimis, menghilangkan kebutuhan untuk memenuhi permintaan untuk menerima data yang diubah setelah mengubahnya.

Merancang skema dan menghubungkannya ke server GraphQL


Sejauh ini, kami telah berbicara tentang cara kerja GraphQL pada klien, dan bagaimana mereka mengeksekusi query. Sekarang mari kita bicara tentang bagaimana menanggapi permintaan ini.

Server raphGraphQL


Untuk menjalankan kueri GraphQL, Anda memerlukan server GraphQL tempat Anda dapat mengirim kueri tersebut. Server GraphQL adalah server HTTP biasa (jika Anda menulis dalam JavaScript, ini bisa berupa server yang dibuat menggunakan Express atau Hapi), yang melampirkan diagram GraphQL.

 import express from 'express' import graphqlHTTP from 'express-graphql' import schema from './schema' const app = express() app.use('/graphql', graphqlHTTP({ schema: schema, graphiql: true })) app.listen(4000) 

Dengan "bergabung" dalam suatu skema, kami maksudkan suatu mekanisme yang meneruskan permintaan yang diterima dari klien melalui skema tersebut dan mengembalikan jawaban untuknya. Itu seperti sebuah saringan udara yang melaluinya udara memasuki ruangan.

Proses "penyaringan" dikaitkan dengan permintaan atau mutasi yang dikirim oleh klien ke server. Kueri dan mutasi diselesaikan dengan menggunakan fungsi yang terkait dengan bidang yang ditentukan dalam kueri root atau dalam mutasi akar skema.

Di atas adalah contoh kerangka kerja server HTTP yang dibuat menggunakan perpustakaan JavaScript Express. Menggunakan fungsi graphqlHTTP dari paket express-graphql dari Facebook, kami "melampirkan" skema (diasumsikan bahwa itu dijelaskan dalam file terpisah) dan menjalankan server pada port 4000. Artinya, klien, berbicara tentang penggunaan lokal server ini, akan dapat mengirim permintaan melalui alamat http://localhost:4000/graphql .

▍ Jenis data dan penyelesai


Untuk memastikan pengoperasian server GraphQL, Anda harus menyiapkan skema dan melampirkannya.

Ingatlah bahwa kami berbicara tentang mendeklarasikan bidang dalam kueri root atau dalam mutasi root di atas.

 import gql from 'graphql-tag' import mongodb from '/path/to/mongodb' //  -  . ,  `mongodb`     MongoDB. const schema = { typeDefs: gql`   type Nutrition {     flavorId: ID     calories: Int     fat: Int     sodium: Int   }   type Flavor {     id: ID     name: String     description: String     nutrition: Nutrition   }   type Query {     flavors(id: ID): [Flavor]   }   type Mutation {     updateFlavor(id: ID!, name: String, description: String): Flavor   } `, resolvers: {   Query: {     flavors: (parent, args) => {       // ,  args  ,  { id: '1' }       return mongodb.collection('flavors').find(args).toArray()     },   },   Mutation: {     updateFlavor: (parent, args) => {       // ,  args    { id: '1', name: 'Movie Theater Clone', description: 'Bring the movie theater taste home!' }       //  .       mongodb.collection('flavors').update(args)       //  flavor  .       return mongodb.collection('flavors').findOne(args.id)     },   },   Flavor: {     nutrition: (parent) => {       return mongodb.collection('nutrition').findOne({         flavorId: parent.id,       })     }   }, }, } export default schema 

Definisi bidang dalam skema GraphQL terdiri dari dua bagian - dari deklarasi tipe ( typeDefs ) dan resolver . typeDefs berisi deklarasi tipe untuk data yang digunakan dalam aplikasi. Sebagai contoh, sebelumnya kita berbicara tentang permintaan untuk mendapatkan daftar objek flavor dari server. Untuk membuat permintaan serupa ke server kami, Anda perlu melakukan tiga langkah berikut:

  1. Beri tahu skema bagaimana data objek flavor terlihat (dalam contoh di atas, ini terlihat seperti iklan type Flavor ).
  2. Deklarasikan bidang di bidang akar type Query (ini adalah properti flavors dari nilai type Query ).
  3. Menyatakan resolvers.Query Fungsi pengenal objek type Query ditulis sesuai dengan bidang yang dideklarasikan di bidang akar type Query .

Sekarang mari kita perhatikan typeDefs . Di sini kami memberikan informasi skema tentang bentuk data kami. Dengan kata lain, kami memberi tahu GraphQL tentang berbagai properti yang mungkin terkandung dalam entitas dari tipe yang sesuai.

 type Flavor { id: ID name: String description: String nutrition: Nutrition } 

Deklarasi type Flavor menunjukkan bahwa objek flavor dapat berisi bidang id dari ID tipe, bidang name String tipe, bidang description tipe String dan bidang nutrition tipe Nutrition .

Dalam hal nutrition kami menggunakan di sini nama dari tipe berbeda yang dideklarasikan di typeDefs . Di sini, type Nutrition membangun menggambarkan bentuk data gizi popcorn.

Perhatikan fakta bahwa di sini, seperti pada awal materi ini, kita berbicara tentang "aplikasi" dan bukan tentang "database". Dalam contoh di atas, diasumsikan bahwa kita memiliki database, tetapi data dalam aplikasi dapat berasal dari sumber apa pun. Bahkan bisa berupa API pihak ketiga atau file statis.

Sama seperti yang kami lakukan pada deklarasi type Flavor , di sini kami menentukan nama bidang yang akan terkandung dalam objek nutrition , menggunakan, sebagai tipe data bidang ini (properti), apa yang di GraphQL disebut tipe data skalar. Pada saat penulisan ini, GraphQL mendukung 5 tipe data skalar bawaan:

  • Int : menandatangani integer 32-bit.
  • Float : angka floating-point presisi ganda dengan tanda.
  • String : urutan karakter yang dikodekan dalam UTF-8.
  • Boolean : Boolean true atau false .
  • ID : pengidentifikasi unik yang sering digunakan untuk memuat objek berulang kali atau sebagai kunci dalam cache. Nilai ID tipe diserialisasi dengan cara yang sama dengan string, namun, indikasi bahwa tipe ID memiliki nilai ditekankan oleh fakta bahwa nilai ini tidak dimaksudkan untuk ditampilkan kepada orang-orang, tetapi untuk digunakan dalam program.

Selain tipe skalar ini, kami juga dapat menetapkan properti untuk tipe yang kami tentukan sendiri. Inilah yang kami lakukan dengan menetapkan properti nutrition dijelaskan dalam type Flavor , tipe Nutrition .

 type Query { flavors(id: ID): [Flavor] } 

Di konstruk type Query , yang menjelaskan tipe akar Query ("kueri root" yang telah kita bicarakan sebelumnya), kami menyatakan nama bidang yang bisa diminta. Dengan mendeklarasikan bidang ini, kami, di samping itu, bersama dengan tipe data yang kami harapkan untuk kembali, tentukan argumen yang mungkin datang dalam permintaan.

Dalam contoh ini, kami mengharapkan kemungkinan penerimaan argumen id dari ID tipe skalar. Menanggapi permintaan seperti itu, sebuah array objek diharapkan perangkat yang menyerupai perangkat tipe Flavor .

▍Menghubungkan pengenal query


, type Query field , , -.

— , GraphQL, , «». resolvers , Query , , flavors , . flavors , type Query .

 typeDefs: gql`…`, resolvers: { Query: {   flavors: (parent, args) => {     // ,  args    { id: '1' }     return mongodb.collection('flavors').find(args).toArray()   }, }, … }, 

- . parent — , , args , . context , . «» ( — , ).

, , . GraphQL « » . , , .

GraphQL , , . JSON-, JSON-, ( GraphQL ).

- flavors MongoDB, args ( ) .find() , , .


-, GraphQL, , , , nutrition . , , Nutrition , , , , flavor . , / .

GraphQL , type Flavor nutrition type Nutrition , . , , flavor .

 typeDefs: gql`   type Nutrition {     flavorId: ID     calories: Int     fat: Int     sodium: Int   }   type Flavor {     […]     nutrition: Nutrition   }   type Query {…}   type Mutation {…} `, resolvers: {   Query: {     flavors: (parent, args) => {…},   },   Mutation: {…},   Flavor: {     nutrition: (parent) => {       return mongodb.collection('nutrition').findOne({         flavorId: parent.id,       })     }   }, }, 

resolvers , , Query , Mutation Flavor . , typeDefs .

Flavors , , nutrition -. , Flavor . , : « , nutrition , type Flavor ».

MongoDB, , parent , -. , parent , , , flavors . , flavor , :

 { flavors {   id   name   nutrition {     calories   } } } 

flavor , flavors , nutrition , parent . , , , MongoDB, parent.id , id flavor , .

parent.id , nutrition flavorId , flavor .


, , . , . type Mutation , , updateFlavor , , .

 type Mutation { updateFlavor(id: ID!, name: String, description: String): Flavor } 

: « , updateFlavor id ID ( , ! , GraphQL , ), name String description String ». , , Flavor ( — , id , name , description , , , nutrition ).

 { typeDefs: gql`…`, resolvers: {   Mutation: {     updateFlavor: (parent, args) => {       // ,  args    { id: '1', name: 'Movie Theater Clone', description: 'Bring the movie theater taste home!' }       //  .       mongodb.collection('flavors').update(         { id: args.id },         {           $set: {             ...args,           },         },       )       //  flavor  .       return mongodb.collection('flavors').findOne(args.id)     },   }, }, } 

- updateFlavor , : , , — , flavor .

, , flavor . ?

, , . , flavor , .

args ? , . , , , 100% , . , , , , , .

GraphQL?


, , , , , GraphQL-API.

, GraphQL , . , . , . , , , GraphQL REST . , , , GraphQL.

▍ ,


, HTTP-, , , , — . GraphQL , , , , ( ).

, , ( — ), GraphQL .

▍ , ,


, , « ». , , , . . GraphQL .

▍ ,


REST API, : , . , -, iOS Android, API . , , , , « » .

, , , HTTP, API (, , ).

▍ GraphQL — ? REST API GraphQL?


, . . , , GraphQL . GraphQL, . , , , . , , .

, GraphQL , , , . GraphQL , Apollo Relay, .

GraphQL — , , . graphql ( express-graphql , ) — . , GraphQL - . , -, , , , .

Ringkasan


, GraphQL , . GraphQL , , , . , , , , GraphQL.

, : GraphQL . GraphQL . , GraphQL, , , , , , , .

— , GraphQL — , , . GraphQL , . , GraphQL — , , , . . , , , , , , GraphQL.

Pembaca yang budiman! GraphQL — , .

Source: https://habr.com/ru/post/id445268/


All Articles