1. Trang chủ
  2. » Luận Văn - Báo Cáo

lỗ hổng sql injection trong các ứng dụng sử dụng graph ql

73 0 0
Tài liệu được quét OCR, nội dung có thể không chính xác
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Nội dung

1Lo Hong Sql Injection Trong Cac Ung Dung Su Dung Graph Ql1Lo Hong Sql Injection Trong Cac Ung Dung Su Dung Graph Ql1Lo Hong Sql Injection Trong Cac Ung Dung Su Dung Graph Ql1Lo Hong Sql

Trang 1

HỌC VIỆN CÔNG NGHỆ BƯU CHÍNH VIÊN THÔNG

KHOA CONG NGHE THONG TIN I

Trang 2

LOI CAM ON

Lời đầu tiên, em xin gửi lời biết ơn sâu sắc tới Thầy giáo TS Nguyễn Ngọc Điệp đã tận tình chỉ bảo, hướng dẫn em trong không chỉ quá trình thực hiện đô án này, nhờ sự giúp đỡ và những chia sẻ của Thây, em đã có những định hướng riêng cho tương lai của mình

Em xin chân thành cảm ơn các Thầy, Cô trong Khoa Công nghệ Thông tin 1 nói riêng và toàn thê các cán bộ của Học viện Công nghệ Bưu chính Viễn thông nói chung đã tạo điều kiện dé em cé thé hoc tap va phat triển bản thân trong một môi trường rất tốt Cảm ơn các Thây Cô đã cung cấp cho em không chỉ kiến thức mà còn là kỹ năng sông, đó là những hành trang hữu ích cho em trên chặng đường dài phía trước của cuộc đời

Em xin gửi lời cảm ơn đến anh chị làm việc tại Trung tâm an ninh mạng Cyber Security Division thuộc Công ty Cổ phân Hệ thống Thông tin FPT Information System đã cung cấp cho em những kiến thức về lập trình, an ninh mạng, kiểm thử xâm nhập và tạo điều kiện cho em hoàn thiện đồ án này

Cuôi cùng, em xin cảm ơn gia đình, bạn bè, những người đã luôn ở cạnh, quan tâm, giúp đỡ và ủng hộ đê bản thân em có thê hoàn thành được đô án này

Em xin chân thành cảm ơn]

Hà Nội, ngày 31 tháng 12 năm 2021

Sinh viên thực hiện

Phạm Hải Vũ

Trang 3

NHAN XET, DANH GIA, CHO DIEM

(Của Người hướng dẫn)

ĐH 2 Đ 0 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000660000600e0ee°eee°e0ee°e°e°ee°e°e°e Á ĐH 2 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600060000ee°ee ĐA 2 20 000000000000000000000000000000000000000000000000400000000000000000000400000000000000000000000000000000000000000000000000000606060600e006ee°66 Đ 00 000000000000000000900000000000000000000000000000000000000000000000000000000000000000000000000900009090000000900000000060000060096090eeeee0eeee°eee°e°e

9 0000000000009000000900000000000000000000000000000000000000000000000000000000000000000900000000900009090009600009060009600006060000600606090e0eee°eeeee°eee°e°e 99 00000000000090000000000600000000000000000000000000000000000000000000000000000000000000000009000000000000090000000090000009000060009006006060900906616© Á ĐH Đ ĐO 2 ĐC C0 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600090000600ee°ee°e°ee Á ĐH 6 2 A0 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060060006060600006e°66

0 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090000000000000900000909090000009000000090090060909°e°e°ee :

(ký và ghi rõ họ tên)

Trang 4

NHAN XET, DANH GIA, CHO DIEM

(Của Người phản biện)

ĐH 2 Đ 0 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000660000600e0ee°eee°e0ee°e°e°ee°e°e°e Á ĐH 2 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600060000ee°ee ĐA 2 20 000000000000000000000000000000000000000000000000400000000000000000000400000000000000000000000000000000000000000000000000000606060600e006ee°66 Đ 00 000000000000000000900000000000000000000000000000000000000000000000000000000000000000000000000900009090000000900000000060000060096090eeeee0eeee°eee°e°e

9 0000000000009000000900000000000000000000000000000000000000000000000000000000000000000900000000900009090009600009060009600006060000600606090e0eee°eeeee°eee°e°e 99 00000000000090000000000600000000000000000000000000000000000000000000000000000000000000000009000000000000090000000090000009000060009006006060900906616© Á ĐH Đ ĐO 2 ĐC C0 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600090000600ee°ee°e°ee Á ĐH 6 2 A0 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060060006060600006e°66

0 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090000000000000900000909090000009000000090090060909°e°e°ee :

(ký và ghi rõ họ tên)

Trang 5

MỤC LỤC

M.9s80)00/905)0)°0200 vii DANH MUC CAC TU VA THUAT NGU VIET TAT wu ecsesssesssesssessseesseesneesneesneesnes ix €)/9089:0096909Ẽ 9 007 .- 1

CHUONG 1: CONG!NCHIFZGRAPHOP! 101 xin Henhe: lethikim32079 @hotmail.cony

1.1 Tong quan về GraphQLL - - ¿ % + SE SE SE+E£E£EEEEE+EEEEEEEEEErkrkeEerkrkrkrkrree 2 JJZN (c1 nốe 2 1.1.2 Lịch sử phát triển của GrapnQL - - + + +s+s+E+E£EkEk+keEeEererkrkexererees 2

1.1.3 Kiến trúc triển khai GraphQLL . - - + 2 SsS‡ESE‡E‡EEEE‡EeEEEEekerrrkererered 4

1.1.3.a Máy chủ GraphQL kết nối trực tiếp với cơ sở dữ liệu - 5 1.1.3.b Máy chủ GraphQL tích hợp với các hệ thống săn Có . - 5

1.1.3.c Kiến trúc kết HỢpD - «+ sec SSkSEEEEEEEEEEEEEEEEEEEEEErrkrkrkrkrkrkeree 6

1.1.4 Các thành phần của Graph(QI - - - St E‡EvEvEEEEEEEkrkeketeteeeeerrrsrrree 6

1.1.5 Hệ thống kiểu dữ liệu (Tp€ SySÉ€INI) .- <5 EEEEEEEEeErkekekererrree 7

1.1.5.a Kiều dữ liệu đối J150/1⁄1(0)/)14511A)/-2T Ta 7

1.1.5.b Kiểu dữ liệu truy vấn và đột biến (Query and Mutation tfype) 9 1.1.5.c Kiểu dữ liệu vô hướng (ScaÌ4r fyJ0€) c-¿- -cc+c+EeEeEeEeEerererererereeeeed 10

1.1.5.d Kiểu dữ liệu liệt kê (Enumeration a2 em 10

1.1.5.e Bổ nghĩa List và Non-null (List and Non-null type modifier) II ITBNNI/12/i 5 0 aưudầẪddẪẢ L II ằ số 12 I.1.5.g Dạng liên hợp (UHIOH ÍJD€) c1 1 ke 13 1.1.5.h Dạng đâu vào (HH fVJD€) ¿- - + 5£ k+E+E‡E+E£EEEEeEeEkeEerkexerkererkd 13 1.1.6 Ngôn ngữ truy vấn (Query ÏaI1g1Iđ8€) 5-5-5 Sxct‡EEekeEerrterereeeee 14

NT n6 22

l.1.8 Thực Hi (EXX€CHẨ[OHH)) 0 1113113311111 11111 vn ky 26

1.1.9 Chỉ tiết cấu hình kiểu (Type infr0sp€€fÏOHI) - Set ct+keteteeerereree 27

1.2 Đánh giá ưu điểm và nhược điểm . 2 2-5 + E2 £E+EzEeEerrsrkrrrree 29

An, an 30 1.2.2 Nhurợc đÏỄHM - - -kSSt+k EEEEEEEEEEETEEEETET E1 T111 1111111110111 crerrrkg 31

1.3 Kết chươnggg - ¿St SE+ESx‡ SE EEEEEEE12111 2111121111111 11111111111 31

Trang 6

CHUONG 2: LO HONG SQL INJECTION TRONG GRAPHQL, API 32 2.1 Cac van đề về bảo mật trong GraphQ\L . - 2 2 2 s+seEeE£x+x+xererees 32 2.1.1 Rị rỉ các Ait TEU NNAY CẲHH 11v vn re 32 2.1.2 Kiểm sốt quyên truy cập dữ liệu - + St SE+k+EeEeEerrtekererred 33

2.1.3 Tan cơng từ chối zdịch VWile-bi-loi xản-Hienhe:lethieim34039@hotmail:eột

2.1.4 Lơ hơng báo mật trong các thành phân tích hợp 36 2.1.5 Lỗ hồng bảo mật xuất phát từ dữ liệu đầu vào -¿- - s©s+ssee: 36 2.2 Lỗ hồng SQL Injection trong GraphQL API ¿5-5 2 5+ =2 5+2 37 2.2.1 LO hong SOL Irije€fiOH - - + SE E‡E‡EEEEEEEEEEEEEEEEEEEEEEEEEErkrkrkererrkrkd 37 X»Z/nẴ con, 2n 6 nan 37 2.2.1.b Tấn cơng In-bandl SQL Ïnj€CfÏOH - c6 St +k‡E‡EeEeEEEkrteterererered 38

2.2.1.c Tấn cơng Blind SQL ÏnjeCtiOH -.: 5c+©5c>c+ccxt+eterrtsrxrrrvsrresee 38

2.2.1.d Tấn cơng Out-of-band SQL Inj€CfÌOII .- «+ 255k +t+E+E+EeEexereeei 39 2.2.2 NGUYEN TNA a4 sa 39 2.2.3 Các bước KÏidL ÍÏLẮC - - 111111 081111 1111 11 111 vn keo 39 2.2.3.a Thu thập thƠng ẨITI - - - - - «<< 099991191 011 1 1 ket 39

»2 80:1 i10 ỶÀäõŸcŨaiaiiii 40

2.2.4 Cơng cụ hỗ trợ khiai thác - +55 SE SE EEEEEEEEEEEEErrrkgrerrrerrkg 40

N1 J'c.//02/ 000, 0n 41 2.2.5 PRONG CHONG o.cccccccccccccccscsssccsssssssssessevsvsvevevsvsvavavsvevssasasacacacecsensvsvavsvevseens 42 2.3 K@t CHUOTG oo ccceccccccccsccscsesesscecscsvsvsscecavsvsvsucecavsvsvsusecavsvsvsesacavavsveveasavevaeess 42

CHUONG 3: XAY DUNG MOI TRUONG LAB DE THU NGHIEM TAN CONG

SQL INĐJECTION TRONG GRAPHQL, API - 5 5333322 £++eeeeeeeeeeeeees 43 “n9: 5 hs (a(liÍ1ÍiIƠOƠƠ 43 3.1.1 Damn Vulnerable GraphQL Application - 5555555 ssss+ 43 3.1.2 Generic UNIVeP ity 30000 TH gen 45 SN ) 008nnnee “31T 46 3.2 Phát triển mơi trường lab - - - sStx+E+E#EvEEEE+EeEEEEEEEEskrEeEererkrkerrrrrees 47 “TC 1 8 .ố ố 47 3.2.1.a Mục tiêu phát tFÏÊ HN -c- SE SE *EEEEEEEEEEEEEEEEEEEEEEEEEEEErkrkrkekrrererkred 47 3.2.1.b Đối trợng hướng AEN veccecccccccccsscsvssesvessvevssssvsvssssvsssessvssevsvsrsevsvereaveee 47 3.2.2 MO ta chive nang CÏHÍHÏH ng net 48

Trang 7

3.2.2.a Cung cấp các thông tin và cách cài đặt lab - + 2-5 s5s+s sec: 48

3.2.2.b Tự động thiết [Gp CO SO AU lIỆU S555 S5 S511 1155555555555 48 3.2.2.c Thiết lập mức độ bảo mật cho các dạng kỹ thuật khai thac SQL Injection

3.2.2.d Thực hành các kỹ thuật khai thác SQL ÏInJeCHOH << <+ 49

3.2.2 G10 điỆH ÏŒÖ, 0 1H nh 49

3.3 Thử nghiệm khai thác SQL Injection trên môi trường lab phát triển 54

SShI (I1 4, ,.18n6n6e.ốẶeẶaa ốẮỐa 54 3.3.1.a Error-based SQLL ÏHJ€CÍIOTN << << + + ‡**vv£+veeeeeeeeeeeeeeess 54 3.3.1.b Union-based SQL ÏHJ€CÍIOH << + 13388831 VVEEEsseeeeeeeess 55 3.3.1.c Boolean-based SQL ÏHJ€CHHOlH <1 EEEEttseeeeeees 56 3.3.1.d Time-based SQL ÏnJ€CHOH 5 << + + *+*+vvv+veeeeeeeeeeeeeeeeeeeees 57 3 1.e Quf-oƒ-band SQL ÏTIJ€CÍÍOHH c5 << 133388833911 VVEEEsseeeeeeeeeres 59

k2 115.171, TT NỹẺẺ ốố.é.aaaŨ 61

3.4 K@t CHUONG oo ccccccccccesscscecscscececscscscscscscsesssssssescscscsvscsvsvstsvsvsvscsesssseseeess 61

4100090000127 62 IM.9)58)/10/94V.9080508957.2) 0.3: 63

Trang 8

DANH MỤC HÌNH VẾ

Hình 1.1: Một số công ty đang sử dụng GraphQL - 2 + 2k E+E£E£EE+EeEzEeErEEerxrxees +

Hình 1.2: Máy chủ GraphQL kết nối trực tiếp với cơ sở dữ liệu - - ¿2 + z+x+s+£z£+zx2 5

Hình 1.3: Máy chủ GraphQL tích hợp với các hệ thống sẵn có - + 2s 2+2 £z£szxze: 6

Hình 1.4: Kiến trúc kết hợpp - ¿- - + + kE£SE+E+k£EEE+EEEEEEEEEEEEE E1 1151111111111 111111 6

Hình 1.5: Thống kê mức độ phổ biến của GraphQL trong năm 2020 ¿2 252: 30 Hình 2.1: Báo cáo về lỗ hồng tại HackerOne 2 ¿2 2S E+E£EE+EE+E£EE+EEEeEEzEerxrrerveei 34

Hình 2.2: Báo cáo về lỗ hồng tại Gitlab 2-5-5 kSSk‡EEEE*EEEEEEEEEEEEEEEEEEEEEEEEEEEkrkerkrkrrred 35

Hình 2.3: Báo cáo về lỗ hồng tại HackerOne -¿- - 2+ £©E+E£EE+E£EE+E+EEEEEEEEEEEEEErEeEerkrers 36

Hình 2.4: SQLi vẫn là vecor tân công web hàng đầu trong các cuộc tân công mạng 37 Hình 2.5: Giao diện chính của công cụ SQ map - - G5 E332 EEESSEEerseseekke 4] Hình 2.6: Giao diện chính của công cụ GraphQQLmap << << + 11 *+ssssseeeeeese 4] Hình 3.1: Giao diện chính của Damn Vulnerable GraphQL Application 44 Hình 3.2: Giao diện chính của GenerIC nIV€TSIVY c5 522 VVVEExseeeeeeeeeeeese 45 Hình 3.3: Giao diện đăng nhẬp - - - - - 1118331111183 111118 9 1111 ng ng ve 50 Hình 3.4: Giao diện chính sau khi đăng nhập thành công - + «+ ++++++*eex++ 50 Hình 3.5: Giao diện cung cấp các thông tin và cách cài đặt lab ¿- - 2 s+sec+zszxszxd 51

Hình 3.6: Giao diện chức năng thiết lập cơ sở dữ lIỆU S22 1 111v 51 Hình 3.7: Giao diện thực hành các kỹ thuật khai thac SQL Injection . - 52 Hình 3.8: Giao diện xem mã nguôn của một mức bảo mật với từng kỹ thuật khai thác 52

Hình 3.9: Giao diện xem gợi ý giúp người dùng có thể thực hiện khai thác lỗ hồng 53

Hình 3.10: Giao diện xem mã nguồn của các mức tất cả các bảo mật với từng kỹ thuật khai ¡2 53

Hinh 3.11: Giao dién thiét lập mức độ bảo mật cho các dạng kỹ thuật khai thác SQL Injection

Hình 3.12: Truy vẫn GraphQL có chứa payload khai thác . ¿- - + + +x+xe£zEezzxerrxd 54 Hinh 3.13: Tén cơ sở dữ liệu đang sử dụng - - << SH kg 55 Hình 3.14: Truy van GraphQL có chứa payload khai thác . - 2-5 2s ££szE+£zxzzzzxd 55 Hình 3.15: Thông tin của toàn bộ các tài khoản người dùng có trong cơ sở dữ liệu 56 Hình 3.16: Truy vấn GraphQL có chứa payload khai thác ¿2-5 2 2 s+s+££££+x+Ez£ezxzx4 57

Trang 9

Hình 3.17: Kết quả cho thấy câu truy vấn SQL với payload trả về kết quả true - 57 Hình 3.18: Truy van GraphQL có chứa payload khai thác . - 2 + 2+ z£s+£+£zxexszxd 58

Hình 3.19: Thời gian máy chủ trả về phản hôi là 3,4s - ¿2 52s 2+E+£££szEe£zxzzsred 59

Hình 3.20: Truy van GraphQL có chứa payload khai thác 2-5 2+s+sz+s£s+£zzxze: 60

Hình 3.21: Yêu cầu DNS chứa thông tin về phiên bản MySQL mà lab đang sử dụng 60

Trang 10

DANH MUC CAC TU VA THUAT NGU VIET TAT

CWE Common Weakness Enumeration

Mot hé thống phân loại các

điểm yếu và lỗ hồng của phần

mềm

HTML, Hypertext Markup Language Ngôn ngữ đánh dấu Siêu văn

JSON JavaScript Object Notation

Định dạng lưu trữ thông tin có cau tric duoc str dung dé truyén

dữ liệu giữa máy chủ và máy

khách

REST Representational State Transfer

Kiéu kién tric phan mém duoc tạo ra đê hướng dân thiệt kê và

phát triên kiên trúc cho ứng

Một loại lỗ hông bảo mật có thé

được tìm thấy trong một số ứng

dụng web

Trang 11

GIỚI THIỆU ĐỎ ÁN

Hiện nay, ứng dung web đang ngày càng phổ biến và phát triển mạnh mẽ đề đáp ứng các yêu cầu của các doanh nghiệp, tổ chức và thỏa mãn nhu cầu của người dùng Các ứng dụng web ngày nay có khả năng cung cấp dịch vụ kinh doanh nói riêng và các dịch vụ quản lý nói chung cho các doanh nghiệp hay tổ chức một cách vô cùng hiệu quả Trong bối cảnh chuyền đôi số đang được đây mạnh thì đã và đang có một số lượng

rất lớn các loại hình dịch vụ được cung cấp thông qua ứng dụng web và hiệu suất của

chúng được đảm bảo thông qua thời gian xử lý và các chức năng cung cấp thông tin Đi kèm với sự phát triển đó các công nghệ mới đề phát triển các ứng dụng web cũng ngày càng được ra đời nhiều hơn, giúp đơn giản hóa quá trình phát triển ứng dụng đề đáp ứng nhu cầu ngày một mạnh mẽ của các doanh nghiệp, tổ chức Một trong số những công nghệ đáng chú ý gần đây là GraphQL Đây là một giải pháp mới được phát triên bởi Facebook, cung cấp cung cấp cho các lập trình viên một phương thức hoàn toàn mới để phát triển các web API sử dụng cho ứng dụng web Với những thế mạnh của mình, GraphQL được dự đoán sé là tương lai mới của web API

Nhưng cũng giống như tất cả các công nghệ mới, GraphQL cũng đi kèm với những vấn đề về bảo mật Các vẫn đề này hoàn toàn có thể gây ra những ảnh hưởng về mặt an toàn bảo mật cho các API sử dụng GraphQL, khiến chúng trở thành mục tiêu tiềm năng cho các cuộc tấn công mạng

Đây là lý do em lựa chọn đề tài “Lỗ hỗng SQL Injection trong các ứng dụng sử dụng GraphQL” với mục đích tập trung nghiên cứu về công nghệ GraphQL và lỗ hồng SQL Injection trong cac tng dung web su dung GraphQL API

Đồng thời, nhằm nâng cao hiểu biết của các bạn sinh viên ngành công nghệ thông tin nói chung về GraphQL và lỗ hồng SQL Injection, em cũng sẽ ứng dụng GraphQL để phát triển một môi trường lab hỗ trợ thực hành khai thác đầy đủ các dạng SQL

Injection trong GraphQL, API Môi trường lab này được tạo ra với mục tiêu cung cấp một môi trường hỗ trợ giảng viên/sinh viên giảng dạy/thực hành về bảo mật GraphQL nói chung và lỗ hồng SQL Injection nói riêng Bên cạnh đó cũng giúp các lập trình viên mới tiếp cận với GraphQL hiểu rõ hơn về các quy trình bảo mật ứng dụng web sử dung

GraphQL API

Với những mục tiêu như trên, bô cục đô án của em sẽ bao gôm 4 chương theo câu trúc như sau:

e Chương 1: Công nghệ GraphQL

e Chwong 2: Lé hong SQL Injection trong GraphQL API

e Chuong 3: X4y dung mdi trudng lab thử nghiệm tan cong SQL Injection trong GraphQL API

e Chuong 4: Két luan

Trang 12

CHƯƠNG 1: CÔNG NGHỆ GRAPHQL

Chương I trình bày tổng quan về công nghệ GraphQL, bao gồm các mục như: lịch sử phát triển, các thành phần của GraphQL Đồng thời chương này phân tích tu điểm và nhược điểm của GraphQL so với phương thức giao tiếp API hiện có, cụ thể hơn là REST

1.1 Tổng quan về GraphQL

1.1.1 Gioi thiéu

GraphQL là một ngôn ngữ thao tác và truy vấn dữ liệu mã nguồn mở cho các API [1] OraphQLL không có gì liền quan với các dạng cơ sở dữ liệu nói chung hay các dạng cơ sở dữ liệu dạng đồ thị như Neo4j nói riêng Từ “Graph” xuất phát từ ý tưởng thu

thập dữ liệu trên lược đồ API (API graph) thông qua các trường và trường con, còn

“Q17 là viết tắt của ngôn ngữ truy vấn (guery language) Chính vì vậy mà GraphQL có thê được sử dụng rất hiệu quả trong bất kỳ ngữ cảnh nào mà API cần được sử dụng

GraphQL được Facebook phát triển nội bộ vào năm 2012 và được phát hành rộng

rãi vào năm 2015 Vào ngày 7 tháng 11 năm 2018, dự án GraphQL đã được chuyền từ

Facebook sang GraphQL Foundation mới được thành lập bởi hiệp hội thương mại công

nghệ phi lợi nhuận Linux Foundation Từ năm 2012, quá trình phát triển của GraphQL tudn theo mét “timeline” trién do Lee Byron - tác giả của GraphQL đặt ra Mục tiêu của Byron là làm cho GraphQL phô biến hơn trên các nên tảng web

GraphQL cung cấp cho các lập trình viên một phương thức khác so với REST và các kiến trúc dịch vụ web khác đề phát triển các web API Giống với các API sử dụng REST thông thường, các API sử dụng GraphQL cũng hoạt động theo mô hình máy khách-máy chủ GraphQL cho phép máy khách (cliem:) xác định câu trúc của dữ liệu cần truy vấn khi gửi yêu cầu HTTP(MTTP requesi) lên máy chủ (server) Máy chủ sau đó sẽ trả về dữ liệu có cấu trúc tương ứng thông qua phản hồi HTTP(MTTP response)

Từ đó sẽ ngăn chặn được việc có quá nhiều dữ liệu được trả về cho máy khách Lý do

cho việc này đến từ tính linh hoạt và phong phú của các ngôn ngữ truy vấn cơ sở dữ liệu như SQL Hai tính chất này của các ngôn ngữ truy vấn cơ sở dữ liệu sẽ làm tăng thêm độ phức tạp không cần thiết đối với các API đơn giản

Hiện nay, GraphQL đã hỗ trợ rất nhiều các ngôn ngữ lập trình, bao gồm Haskell, Javascript, Perl, Python, Ruby, Java, C++, C#, Scala, Go, Rust, Elixir, Erlang, PHP, E,

D va Clojure [2]

1.1.2 Lịch sử phát triển của GraphQL GraphQL bắt đầu được nhen nhóm phát triển vào thời điểm xuất hiện sự chuyền dịch sang các thiết bị di động Đây là thời điểm mà chiến lược phát triển ứng dụng trên

Trang 13

các thiết bị của Facebook không khả thi do các vấn đề liên quan đến mức sử dụng mạng cao khi áp dụng HTML5 trên các thiết bị di động Do đó, Facebook đã quyết định xây dựng lại các ứng dụng trên các thiết bi di động từ đầu băng cách sử dụng các công nghệ hoàn toàn mới

Vấn đề chính của Facebook khi triển khai ứng dụng trên các thiết bi di dong nam 6 tính năng Bảng tin (News Feed) Đây là một chức năng có yêu cầu rất phức tạp khi phải nó yêu câu rất nhiều thông tin như các bài đăng, tác giả của các bài đăng, nội dung bài đăng, danh sách các bình luận và những người đã thích bài đăng Mỗi bài đăng đều được

kết nói, long vào hoặc đệ quy với nhau Các API hiện tại không được thiết kế để cho

phép các lập trình viên tạo ra tính năng Bảng tin với số lượng bài đăng phong phú trên

các thiết bị di động Chúng không có tính chất phân cấp, không cho phép các lập trình

viên chọn những øì họ cần và cũng không có khả năng hiển thị danh sách các bài đăng với nguồn cấp dữ liệu không đồng nhất

Vào năm 2012, Facebook quyết định răng họ cần phải xây dựng một API hoàn toàn mới cho chức năng News Feed đề có thẻ tiếp tục việc triển khai ứng dụng trên các thiết bị di động Đây chính là lúc GraphQL bắt đầu được phát triển và vào tháng 8 năm 2012, ứng dụng Facebook cho iOS 5.0 đã được ra mắt cùng với công nghệ GraphQL mới Nó cho phép các lập trình viên giảm mức sử dụng mạng bang cach thay đổi phương pháp tìm nạp đữ liệu Trong vòng chưa đến 2 năm tiếp theo, GraphQL đã được sử dụng trên phần lớn các chức năng khác của ứng dụng Facebook trên iOS Lần đầu tiên Facebook công khai thông báo về GraphQL là tại hội nghị React.js Conf2015 và ngay sau đó, họ công bố kế hoạch đưa GraphQL thành giải pháp mã nguồn mở

Trên thực tế, trước đây các công ty khác như Netflix hay Coursera cũng đã nghiên cứu các ý tưởng khác nhau đề tạo nên phương pháp tương tác API hiệu quả hơn và cũng đã có một số thành quả nhất định Coursera đã từng thử nghiệm một công nghệ tương

tự GraphQL, cho phép máy khách yêu câu chính xác các dữ liệu cần thiết Netflix cũng

đã cung cấp giải pháp mã nguồn mở của họ có tên Falcor Tuy nhiên, sau khi GraphQL trở thành giải pháp mã nguồn mở, Coursera đã hoàn toàn hủy bỏ dự án thử nghiệm của họ và áp dụng GraphQL trên các sản phẩm của mình Tính đến nay, GraphQL đã được sử dụng trong sản phẩm của rất nhiều các công ty công nghệ lớn như Github, Twitter hay Shopify [3]

Trang 14

Who's using GraphQL?

Facebook's mobile apps have been powered by GraphQL since 2012 A GraphQL spec was open sourced in 2015 and is now available in

any environments and used by teams of all sizes

HOOm ma

Hình 1.1: Một số công ty đang sử dụng GraphQL 1.1.3 Kiến trúc triển khai GraphQL

GraphQL được phát hành dưới dạng một đặc tả mô tả hoạt động của một máy chủ

GraphQL (GraphQL server) Đây là một tập hợp các nguyên tắc về cách xử lý các yêu

cầu và phản hồi cũng như các giao thức được hỗ trợ, định dạng đữ liệu có thê được máy

chủ chấp nhận, định dạng của phản hồi do máy chủ trả về,

Đề gửi một truy vấn đến máy chủ GraphQL, máy khách có thể sử dụng bắt cứ giao thức mạng nào trong tầng giao vận miễn là giao thức đó khả dụng Thông thường, các

giao thức thường được sử dụng sẽ là TCP hoặc WebSocket Một điều cần chú ý nữa, máy chủ GraphQL là độc lập với cơ sở dữ liệu vì vậy, lập trình viên có thé str dụng nó

với bất cứ dạng cơ sở dữ liệu nào

Như vậy, có thể thấy luồng hoạt động của mô hình máy khách-máy chủ trong

GraphQL như sau: -_ Máy khách thực hiện gửi truy vẫn GraphQL đến máy chủ thông qua các yêu cầu

HTTP Các truy vẫn này thường sẽ được gửi dưới dạng một chuỗi

- May chủ sẽ nhận yêu cầu HTTP và trích xuất chuỗi truy vấn Sau đó, máy chủ

xác thực và xử lý truy vẫn GraphQL dựa theo cú pháp GraphQL mặc định và

lược đồ GraphQL (GraphQL schema)

- Gidng với các máy chủ API khác, máy chủ GraphQL cũng thực hiện các lệnh

gol đến cơ sở dữ liệu hoặc các dịch vụ khác đề truy xuất dữ liệu được máy khách

yêu cầu

- _ Cuối cùng, máy chủ sẽ tổng hợp lại dữ liệu và trả về cho máy khách dưới dang

một đối tượng JSON thông qua phản hồi HTTP

Một máy chủ GraphQLL có thê được triển khai bang một trong ba kiến trúc sau: máy

chủ GraphQL kết nói trực tiếp với cơ sở dữ liệu, máy chủ GraphQL tích hợp với các hệ

thống sẵn có hoặc kiến trúc kết hợp từ 2 kiến trúc trên Từng loại kiến trúc sẽ được trình bày chỉ tiết sau đây

Trang 15

1.1.3.a Máy chủ GraphQL kết nối trực tiếp với cơ sở dữ liệu Đây là dạng kiến trúc phố biến nhất cho các dự án không quá phức tạp về mặt hệ thông Đề triển khai, lập trình viên chỉ cần một máy chủ web Máy chủ web này sẽ đảm nhiệm vai trò là máy chủ GraphQL lẫn vai trò là máy chủ cơ sở dữ liệu

Khi máy khách gửi truy vẫn đến máy chủ GraphQL, nó sẽ tiễn hành đọc truy vẫn

và tìm nạp dữ liệu từ cơ sở dữ liệu Quá trình này được gọi là thực thi truy vấn Sau khi

thực thi truy vẫn, máy chủ sẽ trả về cho máy khách một phản hồi HTTP chứa dữ liệu

mà máy khách yêu câu

Với dạng kiến trúc này, GraphQL cũng sẽ không quan tâm đến loại cơ sở dữ liệu

hoặc định dạng được sử dụng đề lưu trữ dữ liệu Điều này có nghĩa là lập trình viên có

thể triển khai kiến trúc này với bất cứ loại cơ sở dữ liệu này, từ các dạng cơ sở dữ liệu

quan hệ như MySQL cho đến các dạng cơ sở dữ liệu phi quan hệ như MongoDB

1.1.3.b Máy chủ GraphQL tích hợp với các hệ thống săn có

Đây là dạng kiến trúc được sử dụng cho các dự án phức tạp về mặt hệ thống Các

dự án này thường đòi hỏi kết nối với các các cơ sở hạ tầng và API sẵn có của doanh nghiệp Những thành phân có thể đã được phát triển và sử dụng trong nhiều năm, khiến cho việc triển khai các dự án mới trên chúng gặp rất nhiều khó khăn Trong dạng kiến trúc này, máy chủ GraphQL có thể được sử dụng để hợp nhất cdc “microservice”, co so

hạ tầng và các API khác trong hệ thống hiện tại Điều nay sẽ ø1úp giấu sự phức tạp của

các bước tìm nạp dữ liệu Băng cách này, máy khách sẽ chỉ cần thực hiện giao tiếp với máy chủ GraphQL đề lấy các đữ liệu cần thiết Sau đó, máy chủ GraphQL sẽ chịu trách

nhiệm tìm nạp dữ liệu từ các hệ thống được tích hợp và trả về cho máy khách

Trang 16

Với dạng kiên trúc này, máy chủ GraphQLL cũng sẽ không quan tâm đên các nguôn

dữ liệu mà nó cân đê tìm nạp các dữ liệu cân thiệt nhăm thực hiện một truy van

Đây là dạng kiến trúc kết hợp từ 2 dạng đã nêu trên Trong dạng kiến trúc này, máy

chủ GraphQL được kết nối trực tiếp với một cơ sở dữ liệu và đồng thời cũng sẽ được

sử dụng để tích hợp các hệ thống sẵn có Lúc này, khi máy chủ GraphQL nhận được

truy vẫn, nó sẽ truy vấn đữ liệu từ cơ sở dữ liệu được kết nối trực tiếp hoặc từ các hệ

1.1.4 Các thành phân của GraphQL

Các thành phần của GraphQL bao gồm: hệ thống kiều dữ liệu (fype sysfem), ngôn

ngữ truy van (query language), xac thuc (validation), thuc thi (execution) và xem xét

Trang 17

nội dung kiểu (/ype introspection) Từng thành phần sẽ được trình bày chỉ tiết trong các

mục tiếp theo [4]

1.1.5 Hé thong kiéu dit ligu (Type system)

Hệ thống kiểu dữ liệu là thành phần có chức năng xác định các kiểu dữ liệu khác

nhau có thể được sử dụng trong một GraphQL API Hệ thống sẽ đóng vai trò chính

trong việc tạo nên lược d6 (schema) cho GraphQL API

Lược đồ là cốt lõi của một GraphQL API Máy chủ GraphQL sẽ sử dụng lược đồ

để xác định và mô tả hình dạng đô thị dữ liệu của API đó Lược đồ sẽ thiết lập hệ thông

phân cấp các loại dữ liệu với các trường cũng như mô tả các chức năng sẵn có cho máy

khách Nói một cách đơn giản hơn, lược đồ được sử dụng để xác định một tập hợp các

kiểu dữ liệu và mối quan hệ giữa các kiều dữ liệu này Nó cũng được dùng để xác định

các tác vụ mà máy khách có thể sử dụng

Như đã trình bày ở trên, hiện nay, GraphQL đã hỗ trợ rất nhiều ngôn ngữ lập trình khác nhau Đề thuận tiện cho việc sử dụng với nhiều ngôn ngữ, GraphQL sẽ sử dụng một loại cú pháp chung để tạo nên lược đồ Cú pháp này được gọi là Ngôn ngữ định nghia luoc d6 (Schema Definition Language) Cu phap nay sé duoc str dung dé khai bdo lược đồ cho các GraphQL API theo hướng độc lập với ngôn ngữ lập trình

Một thành phân được định nghĩa trong lược đồ cần thuộc một trong các kiểu dữ liệu sau:

- _ Kiểu dữ liệu déi tuong (Object type) - Kiéu dé liéu truy van (Query type) - Kiéu dit liéu d6t bién (Mutation type)

- Kiểu đữ liệu vô hướng (Secalar fype)

- Kiéu dit liéu liét ké (Enumeration type) Ngoài các kiểu dữ liệu kế trên thì một thành phần trong lược đồ cũng có thê được

định nghĩa là một /nterface hoac mot dang lién hop (Union type) hay mot dang dau vao

(Input type) Cac thanh phan trong lugc d6 c6 thé sir dung thêm các bồ nghĩa như 1⁄5 và Non-nuil, tùy theo yêu cầu về mặt cấu trúc dữ liệu cho dữ liệu các thành phần đó

Từng kiêu dữ liệu sẽ được trình bày chỉ tiết sau đây

1.1.5.a Kiểu dữ liệu đối tượng (Object type)

Thành phần cơ bản nhất của lược đồ GraphQL 1a kiểu dữ liệu đối tượng, đại diện

cho một đối tượng mà máy khách có thể tìm nạp từ GraphQL API Một kiêu dữ liệu đối

tượng sẽ có thể có nhiều trường, mỗi trường có thê thuộc một kiêu dữ liệu khác nhau

Nói cách khác, kiêu dữ liệu này sẽ bao gồm nhiều trường, các trường này có thê thuộc

các kiểu dữ liệu vô hướng hoặc các kiểu dữ liệu đối tượng khác Cú pháp cơ bản đề định nghĩa một kiểu dữ liệu đối tượng như sau:

Trang 18

type object type name

{

fieldl: data_type field2:data_type fieldn:data_type

Vi du dinh nghia kiểu dữ liệu đối tượng Character trong lugc đồ GraphQL:

type Character { name: String!

- Ménh đề Síring! đại diện cho việc trường øze thuộc kiéu di liéu String va

trường này sẽ không thể mang giá trị rỗng Với định nghĩa như vậy thì máy

khách sẽ luôn nhận được dữ liệu của trường nzne dưới dạng một chuỗi ký tự - Ménh dé / Episode]! đại diện cho việc truong appearsIn ánh xạ tới một mảng

các đối tượng thuộc kiểu dữ liệu Episode và mảng này sẽ không thé mang gid trị rỗng Kiểu dữ liệu Episode cũng là một kiểu đôi tượng được định nghĩa trong

lược đồ Với định nghĩa như vậy thì máy khách sẽ luôn nhận được dữ liệu của trường apppearsin dưới dạng một mảng của các phần tử thuộc kiểu dữ liệu

Episode

Cac truong thudc kiểu đối tượng có thể không có hoặc có nhiều tham số, ví dụ như

trường /eng:h trong ví dụ dưới đây:

type Starship { id: ID!

name: String! length(unit: LengthUnit = METER): Float

Trang 19

GraphQL sẽ truyền giá trị vào tham số theo tên cụ thể của tham số đó Trong ví dụ trên

trường /engfh sẽ có một tham số với tén 1a unit

Khi định nghĩa một trường có tham số thì lập trình viên có thể lựa chọn xem việc

máy khách phải cung cấp giá trị cho tham số đó là tùy chọn hay bắt buộc Khi một tham

số không bắt buộc máy khách phải cung cấp giá trị, lập trình viên có thể khởi tạo một

giá trị mặc định Trong ví dụ trên, nếu gia tri cua tham s6 unit khong duoc may khach

`

cung cấp thi gia tri cua né sé dugc mac dinh coi la “METER”

1.1.5.b Kiểu dữ liệu truy vấn và đột biến (Query and Mutation type) Giống với các API khác, GraphQL API cũng cho phép máy khách thực hiện hai

loại tác vụ chính với dữ liệu bao gôm tìm nạp dữ liệu và thay đôi dữ liệu Các tác vụ cụ

thể mà máy khách sử dụng sẽ được xác định trong lược đồ của GraphQL API Đề có thể định nghĩa một tác vụ, GraphQL sẽ cung cấp 2 kiểu dữ liệu đặc biệt là kiểu dữ liệu

truy van và kiểu đữ liệu đột biến Trong đó, kiêu dữ liệu truy vấn sẽ đại diện cho các

loại tác vụ tìm nạp dữ liệu và kiều dữ liệu đột biến đại diện cho các loại tác vụ thay đổi

dữ liệu Một GraphQL API đều có một hoặc nhiều kiểu dữ liệu truy van và có thể có

hoặc không có kiểu dữ liệu đột biến Kiểu dữ liệu truy vẫn và đột biến là các kiều dữ liệu đặc biệt do chúng sẽ xác định

các diém dau vao (entry point) cho 2 tác vụ tìm nạp đữ liệu và thay đổi dữ liệu Ngoài

đặc điểm đó ra thì kiểu truy vẫn và đột biến hoàn toàn giống với kiêu dữ liệu đối tượng và các trường của chúng cũng hoạt động tương tự như các trường của kiêu dữ liệu đối

tượng

Cú pháp để cơ bản để định nghĩa các tác vụ tìm nạp dữ liệu sử dụng kiểu dữ liệu truy vẫn như sau:

type Query {

fieldl: data type

Ví dụ, định nghĩa các tác vụ tim nap dt ligu hero va droid:

type Query { hero (episode: Episode): Character droid(id: ID!): Droid

Trong vi du trén, kiểu dữ liệu truy vấn đã định nghĩa tác vụ tìm nạp dữ liệu hero là

một truy vấn có tham số là episode là một đối tượng thuộc kiêu đữ liệu Episode và sẽ trả về dữ liệu là một đối tượng thuộc kiêu dữ liệu Characrer còn tác vụ tìm nạp đroid

Trang 20

sẽ có tham số là ¿đ có kiểu dữ liệu vô hướng 7D và trả về dữ liệu là một đối tượng có

kiểu dữ liệu Droid Cú pháp cơ bản để định nghĩa các tác vụ thay đổi dữ liệu sử dụng kiểu đữ liệu đột

biến cũng sẽ tương tự:

type Mutation { fieldl: data type

}

1.1.5.c Kiểu dữ liệu vô hướng (Scalar type)

Kiêu đữ liệu vô hướng là kiêu đữ liệu cơ sở (primitive fype) chỉ có thê lưu trữ một giá trị duy nhất Các kiểu dữ liệu vô hướng mặc định mà GraphQL cung cấp là:

- Int: Dai dién cho cdc giá trị số nguyên 32-bit có dấu - _ Floar: Đại diện cho các giá trị số thực dấu phây động có dấu

- String: Dai dién cho cac chuỗi ky tu duoc ma hda theo UTF-8 - Boolean: Dai dién cho cac gia tri true hoac false

- ID: Đại điện cho một số nhận dạng duy nhất, thường được sử dụng đề tìm nạp

một đối tượng hoặc làm khóa cho bộ nhớ cache Kiểu dữ liệu này thường được tuần tự hóa (serialize) giống nhu String

1.1.5.d Kiểu dữ liệu liét ké (Enumeration type)

Kiểu dữ liệu liệt kê cũng gần tương tự như kiêu dữ liệu vô hướng, chỉ khác là kiểu

dữ liệu liệt kê có thê lưu trữ một tập hợp các giá trị khác nhau Kiểu dữ liệu này rất hữu

ích khi dữ liệu của một trường phải nam trong danh sách các tùy chọn được chỉ định Cú pháp đề định nghĩa một kiểu đữ liệu liệt kê như sau:

JEDI

Trang 21

Với định nghĩa trên, bất cứ trường hay tham số nào thuộc kiểu đữ liệu Episode sé có giá trỊ là một trong ba chuỗi “NEWHOPE”, “EMPIRE” hoặc “JEDT'

1.1.5.e Bồ nghia List va Non-null (List and Non-null type modifier) List duoc dinh nghia la mot bổ nghĩa (type modifier), được biểu diễn băng một cặp

dẫu ngoặc vuông bao bọc tên các kiểu dữ liệu đối tượng, kiểu dữ liệu vô hướng và kiểu

dữ liệu liệt kê Bồ nghĩa này có thê được sử dụng đề biêu diễn cho một mảng các giá trỊ

thuộc một kiểu cụ thể Cú pháp để xác định một thành phần có bồ nghĩa /¡s/ như sau:

liệu liệt kê Bổ nghĩa này có thể được sử dụng để biểu diễn cho việc một thành phần

nào đó yêu cầu giá trị khác giá trị rỗng Điều này nhằm đảm bảo sự hiện diện của giá trị trong kết quả truy vấn Cú pháp để xác định một thành phần có bồ nghĩa khác rỗng Non-null như sau:

Cé thé thay trudng name sé thuéc kiéu dit liéu String va cé b6 nghia Non-null Điều này có nghĩa là máy chủ sẽ luôn trả về một giá trị khác rỗng cho trường này Trong trường hợp giá trị của „zne là rỗng, máy chủ sẽ kết thúc quá trình xử lý truy vấn và trả

về thông báo lỗi thực thi cho máy khách

Trường apppearsỉn sẽ thuộc kiêu đữ liệu Episode và có bô nghĩa L¡sr Điều này có nghĩa là máy chủ sẽ luôn trả về một mảng các đối tượng thuộc kiểu dữ liệu cho trường này Đồng thời kiểu trường này cũng được đánh dấu là /Episode!J, có nghĩa là các đối

tượng thuộc kiểu dữ liệu Episode trong mảng kết quả trả về cũng bắt buộc phải có giá

trị khác rỗng Ví dụ:

appearsiIn: null // valid

appearsiIn: [] // valid appearsiIn: ['NEWHOPE', 'EMPIRE'] // valid

Trang 22

Dau chấm than ngay sau /Episode!]! cũng thê hiện rằng mảng dữ liệu trả về cho trường appearsÏn cũng phải luôn khác giá trị rỗng Từ đó có thể suy ra các giá trị thỏa mãn với truong appearsIn:

apbearsIn: null // error

appearsiIn: [] // valid

appearsiIn: ['NEWHOPE', null, 'EMPIRE'] // error

1.1.5.f Interface

Giống như nhiều hệ thống kiểu dữ liệu khác, GraphQL cũng hỗ trợ các Interface Interface là một kiêu dữ liệu trừu tượng, bao gồm một tập hợp các trường nhất định

phải có mà một kiểu dữ liệu khác phải có khi kiểu dữ liệu đó được định nghĩa là sử dụng

giao dién Vi du dinh nghia Interface Character dai dién cho bất cứ nhân vật nào trong

một chuỗi phim:

interface Character { id: ID!

Bắt cứ kiêu đữ liệu nào sử dung Interface Character déu sé co cac truong xuất hiện

trong giao diện này Các trường đó sẽ có các đối số và kiểu trả về giống như đã được

định nghĩa trong Iwerface Character Dưới đây là ví dụ về một số kiểu đữ liệu có thể

Trang 23

Kiéu dit ligu Human dai dién cho các nhân vật là con người còn kiểu dit ligu Droid

đại diện cho các nhân là người máy Có thể thấy 2 kiểu đữ liệu này đều có tất cả các

truong tir Interface Character, nhưng chúng cũng có thêm các trường bồ sung như totalCredits, starships cho cac nhan vat la con nguoi va primaryFunction cho cac nhan vật là người máy

1.1.5.g Dang lién hop (Union type) Dang liên hợp gần giống với giao diện, nhưng chúng sẽ không yêu câu các kiểu đữ liệu có trường chung Ví dụ định nghĩa dạng liên hợp Search Ñesulr:

răng các thành viện trong một dạng liên hợp phải là một kiêu dữ liệu cụ thé Khong thé

tạo dạng liên hợp từ các giao diện hoặc các dạng liên hợp khác

1.1.5.h Dang dau vao (Input type) Trong các ví dụ trên, hầu như tham số của các trường sẽ nhận giá trị là các kiểu dữ liệu vô hướng như /z hay Sring Tuy nhiên, trên thực tế đôi khi máy khách sẽ cần truyền giá trị là các đối tượng phức tạp cho các trường Điều này thường xảy ra với các

tác vụ thay đối dữ liệu, khi máy khách có thê tạo một đối tượng và chuyên thành giá trị

cho một trường Lúc này, lập trình viên có thê định nghĩa một dạng đầu vào đề chứa đối tượng mà máy khách tạo ra Cú pháp đề định nghĩa một dạng đầu vào như sau:

Trang 24

commentary: String

}

1.1.6 Ngôn ngữ truy vấn (Query language) Query language là thành phần tạo nên các câu truy vấn trong GraphQL Máy khách có thê sử dụng query language để thực hiện tương tác dữ liệu từ máy chủ Trong GraphQL, có hai tác vụ chính mà máy khách có thê thực hiện với ngôn ngữ truy vấn:

— Tim nap dir liéu (query)

— Thay d6i dit ligu (mutation)

Cú pháp của một câu truy vân như sau:

can thay d6i di liéu Query_operation là bắt buộc phải có với mỗi câu truy vấn

- Operation_name là mệnh đề xác định tên cho các câu truy vẫn Operation_name chỉ bắt buộc phải có với các API yêu cầu nhiều tác vụ khác nhau để tương tác

với dữ liệu Nhưng nó cũng được khuyến khích sử dụng vì sự hữu ích cho việc

gỡ lỗi và ghi log phía máy chủ Khi xuất hiện lỗi, việc xác định các câu truy vấn

trong mã nguồn theo tên sẽ dễ dàng hơn so với việc phải xác định dựa vào nội dung

- _ Fields là mệnh đề xác định các dữ liệu mà máy khách cần tương tác

Trang 25

query_ name {

máy chủ thực hiện song song

- Ménh dé query_fields là thành phần giúp cho máy khách xác định những dữ

liệu cần lây từ máy chủ

Dưới đây là ví dụ một câu g„ery và kết quả khi thực hiện thành công:

Trong ví dụ trên, tác vụ tìm nạp dữ liệu hero sẽ trả vê gia tri cua truong name cua

một đôi tượng có kiêu dir ligu Character Một trường cũng có thê ánh xạ đến một đối tượng khác Khi đó, máy khách chỉ cần

tạo thêm các trường còn trong trường đó đề lấy dữ liệu từ đối tượng nó ánh xạ đến GraphQL sẽ duyệt các đối tượng có liên quan và các trường của chúng và cho phép máy khách tìm nạp nhiều dữ liệu liên quan chỉ trong một truy vấn Ví dụ câu øery dưới đây có trường #iends ánh xạ đến một mảng các đối tượng thuộc kiểu dữ liệu Character:

{ hero {

Trang 26

"name": "Han Solo"

}, {

"name": "Leia Organa"

khách phải gọi API đề tìm nạp dữ liệu Tham số cũng có thể có nhiều kiểu dữ liệu khác

nhau Dưới đây là ví dụ về một query có sử dụng tham số đề tìm nạp dữ liệu:

Trong mot s6 truong hop, khi c4u query tir may khach co nhiéu tac vu tim nap dit

liệu giống nhau, ví dụ với câu truy van str dung tac vu tim nap human dé lay dữ liệu về

2 đôi tượng có kiểu dữ liệu Human với tham số ¿đ là 1000 và 1001 Với cách viết như

các ví dụ trên, ta sẽ có câu g⁄ery như sau:

Trang 27

Lúc này, sẽ xuất hiện xung đột do máy chủ thực hiện các tác vụ tìm nạp song song

nên không thể phân biệt được máy khách cần lấy dữ liệu từ tác vụ nào Để tránh điều

này xảy ra, máy khách có thê sử dụng bí danh (zias) để đổi tên các tác vụ bị trùng lặp

Ví dụ, với bí danh, câu øuery trên có thê được viết lại như sau:

{

human1000: human(id: "1000") name

height

}

humanl001: human(id: "1001") name

by

"humanlOO1": { "name": "Darth Vader", "height": 2.02

Tiêp tục xét đên một trường hợp khác, giả sử với câu truy vân trên, máy khách sẽ

cân lây dữ liệu về tên và chiêu cao của 100 đôi tượng thuộc kiêu dữ liệu Human Lúc

này câu truy vấn sẽ trở nên phức tạp hơn do sẽ phải liên tục gọi các trường name va heighr ở mỗi tác vụ Đề giải quyết trường hợp này, GraphQL cho phép lập trình viên tao ra cdc Fragment Fragment cho phép máy khách tạo ra nhóm các trường cần phải lấy dữ liệu và đưa chúng vào các tác vụ Fragmen thường được sử dụng để chia các yêu cầu dữ liệu phức tạp thành các phần nhỏ hơn Ví dụ để giải quyết trường hợp trên, có thê su dung cau query nhu sau:

{ human1000: human (1d: "1000")

{

comparisonFields }

humanl001: human(id: "1001")

comparisonFields

}

fragment comparisonFields on Human {

"name": "Luke Skywalker", "height": 1.72

by

"human1001": { "name": "Darth Vader",

"height": 2.02

Trang 28

Trong tất cả các ví dụ ở trên, các tham số đều được cung cấp bên trong câu gwery Tuy nhiên, trong hầu hết các ứng dụng, các tham số cho các trường sẽ động Ví dụ, người dùng có thể cung cấp tham số tùy ý thông các ô tìm kiếm dữ liệu hoặc các bộ lọc

dữ liệu Máy khách có thể chuyền trực tiếp các tham số động vào câu query Tuy nhiên

khi làm như vậy, máy khách sẽ cần tác động vào câu truy vấn trong thời gian chạy và chuyền câu query thành dạng xác định cho GraphQL Thay vào đó GraphQL cung cap một phương pháp khác để xác định các tham số động và cung cấp cho câu query bằng

cách đưa chúng thành giá trị dưới dạng từ điển riêng biệt Các giá trị này được gọi là bién (variable)

Một biến có thể được khai báo như sau:

dữ liệu vô hướng, các giá trị hằng số hoặc một đối tượng đầu vào mà người dùng

có thê định nghĩa trong lược đồ của API Ngoài ra, nếu một biến yêu cầu một giá trị đầu vào khác rỗng thì sẽ cần thêm ký tự ! vào sau variableType

Khi sử dụng các biên, có ba điêu cân thực hiện:

- _ Thay thế các tham số trong câu query bang $variableName

- _ Khai báo §variableName là một trong các biến được chấp thuận bởi câu guery

- ua gia tri cua variableName vao cau query

Vi du cu thé nhu sau:

query HeroNameAndFriends (Sepisode: Episode) { | {

"episode": "JEDI"

"name": "Leia Organa"

Trang 29

}

Trong ví dụ trên, biến $episode đã được khai báo là 1 đối tượng thuộc kiểu dữ liệu

đầu vào Episode được định nghĩa trong lược đồ của API Biến này không yêu cầu một giá trị đầu vào khác rỗng Lúc này, câu guery HeroNameAndFriends sẽ chấp thuận biến $episode Khi đó, máy khách sẽ chỉ cần cung cấp giá trị của biến này dudi dang JSON thay vì cần phải tạo một câu zery hoàn toàn mới Khi thực hiện câu truy vấn với câu query trên, máy chủ sẽ đưa giá trị nhận từ máy khách vào biến $episode trong câu gwery,

thực hiện và trả về dữ liệu cho máy khách

Ngoài ra, lập trình viên cũng có thể gán một giá trị mặc định cho biến Ví dụ, gán giá trị mặc định cho biến §episode:

Khi giá trị mặc định được gán cho một biến, máy khách có thể thực hiện gọi câu

query mà không cần truyền vào giá trị của biên đó Nếu có bât cứ giá trị nào được truyền

vào thì máy chủ sẽ ghi đè giá trị đó lên giá trị mặc định

Việc sử dụng các biến đã giải quyết rất nhiều vẫn đề khi cần phải tạo các câu gwery

với tham số động Tuy nhiên, trong một vài trường hợp, máy khách cần thêm một phương pháp để thay đổi cấu trúc và hình dạng của câu gery bằng cách sử dụng biến Ví dụ, ở máy khách xuất hiện một thành phần giao diện người dùng có chế độ xem tóm tắt và chỉ tiết, trong đó chế độ xem chỉ tiết sẽ yêu cầu nhiều trường cần lấy dữ liệu hơn chế độ xem tóm tắt Lúc này, máy khách sẽ cần phải sử dụng một tính năng mới trong

GraphQL duoc goi la Directive Mot Directive c6 thé được đính kèm với trường hoặc

Fragment Directive c6 thé tac dong dén viéc thu thi tac vu ma cau query yéu cau theo bất cứ cách nào mà máy chủ mong muốn Đặc tả lõi của GraphQL bao gồm 2 loại

Trang 30

Directive rất hữu ích khi máy khách cần hạn chế tình huống cần phải thực hiện thao

tác chuỗi để thêm hoặc xóa các trường ra khỏi kết quả nhận được từ máy chủ Ví dụ,

cau query khi cần thực hiện tác vụ tìm nap hero voi Directive @ include dé bo qua dữ

liệu của trường ƒiend ra khỏi kết quả trả về:

Trong vi du trén, biến $withFriends được khai báo là một biến thuộc kiểu dữ liệu Boolean và được sử dụng làm giá trỊ đề xác định việc thực hién Directive @include di

kèm với trường ƒiends để xác định xem có đưa dữ liệu lẫy từ trường này vào kết quả

trả về hay không Trong trường hợp giá trị bién $withFriends 1a false, két quả trả về sẽ không có đữ liệu lây từ trường #iends

Trong trong hop, trong cau query có một trường trả về một đối tượng là một

Interface hoặc thuộc dạng liên hợp, máy khách sẽ cần sử dụng các /mline fragmen: đề truy cập vào dữ liệu của các trường thuộc một kiểu cụ thể Xem xét ví dụ dưới đây:

Trang 31

Interface Có nghĩa là các đối tượng thuộc kiểu dữ liệu này thể được chia nhỏ thành

thuộc một trong hai kiểu dữ liệu khdc 18 Human hoac Droid, tuy thudc vao bién

$episode Với câu query trực tiếp, máy khách sẽ chỉ có thê lây được dữ liệu của các

trường trong kiêu dữ liệu Character, ví dụ như trường name Đề có thể lây được dữ liệu của một trường trong một kiểu dữ liệu cụ thẻ, máy khách sẽ cần sử dụng một Iniine

fragment với điều kiện về kiêu đữ liệu Trong ví dụ trên, máy khách đã sử dụng 2 Inline

fragment, bao gồm: - .0n Droid: Inline ffagment này sẽ trả về trường prinaryFunction trong trường

hợp đối tượng có kiêu dữ liệu Character mà hero trả về thuộc kiêu dit liéu Droid

- .0n Human: Inline fragment nay sé tra vé truong height trong truéng hop déi

tượng có kiêu dữ liệu Character mà hero trả về thuộc kiểu dữ liệu Human

Các Fragmenr được đặt tên cũng có thé duoc str dụng theo cách tương tự, vì một

Fragmenr được đặt tên luôn có một kiêu được đính kèm

Tuy nhiên cũng có một số tình huống mà máy khách sẽ không thể biết được máy chủ sẽ trả về đối tượng thuộc kiều dữ liệu nào Lúc này, GraphQL cung cấp một ““wera

field' là typename với tác dụng giúp cho máy khách có thê lấy được tên kiểu dữ liệu

của đối tượng trong dữ liệu Ví dụ:

; name "typename": "Human",

Trang 32

Trong cau guery trén, tac vu tim nap df ligu search sé trả về một đôi tượng thuộc

dạng liên hợp Déi tuong nay co thé thudc mét trong ba kiéu dir ligu Human, Droid

hoặc Starship Vi vay, may khách sẽ không thể phân biệt được các kiểu dữ liệu khác

nhau nếu không c6 “meta field” typename

Ménh dé mutation_name 1a tac vu thay đối dữ liệu cần thực hiện Giống với

q„ery, một câu mufafion cũng có thể bao gồm nhiều tác vụ thay đổi dữ liệu Tuy nhiên, trong trường hợp câu mutation c6 nhiéu tac vu thay thi cdc tac vu do sé

được thực hiện lần lượt Điều này nghĩa là nêu máy khách gửi 2 tác vụ giống

nhau trong một truy vấn thì tác vụ thứ hai chỉ được thực hiện khi tác vụ đầu tiên được thực hiện sau đề tránh xảy ra hiện tượng tình huống tương tranh (race conditions)

Mệnh đề param: dafa_value sẽ xác định các tham số và giá trị của các tham số đó cho tác vụ Giống với guery, máy khách có thể trực tiếp cung cấp giá trị các tham số hoặc cung cấp giá trị tham số thông qua các biến

Mệnh đề ƒields xác định các trường máy khách cần lẫy dữ liệu sau khi thực hiện

tác vụ được thực hiện thành công Mệnh đề này rất hữu ích khi thực hiện tác vụ

thay đổi trên các dữ liệu sẵn có, chăng hạn như khi thay đổi giá trị của một

Trang 33

trường, máy khách có thể thay đổi và lay gid trị mới của trường đó chỉ bằng một truy vân

Dưới đây là ví dụ về một câu mwfafion nhận vào giá trị cho các tham số cho tác vụ

thay đôi dữ liệu và thực hiện truy vấn giá trị của các trường đã thực hiện thay đổi thông

1.1.7 Xac thuc (Validation) Bằng cách sử dụng hệ thống kiểu dữ liệu, GraphQL có thể kiểm tra xem một truy vấn có hợp lệ hay không Khi cần thực hiện các truy vấn lồng nhau phức tạp thì thành phần này sẽ cho phép máy chủ và máy khách có một cách thông báo cho các lập trình viên khi truy vấn không hợp lệ đã được khởi tạo mà không cần phải kiểm tra thời gian chạy của truy vẫn đó Giả sử một câu query không hợp lệ như sau:

"message": "Cannot spread fragment

}

Trang 34

Câu guery trên không hợp lệ do một Fragment khong thé tu tham chiéu dén chinh

nó Một lỗi khác thường xảy ra khiến cho một truy vẫn trở thành đó là gọi đến các

trường không t6n tai trong một kiểu dữ liệu Ví dụ:

# INVALID: favoriteSpaceship does not exist on Character

field \"favoriteSpaceship\" on type

Trong câu guery trên, tác vụ tìm nạp dữ liệu hero sẽ trả về một đối tượng thuộc kiểu

dữ liệu Characfer Tuy nhiên, câu query lại yêu cầu lấy dữ liệu về trường

favoriteSpaceship Trường này không có trong định nghĩa của kiểu dữ liệu Character Vì vậy truy vấn với câu query trên là không họp lệ

Một điều khác cũng cần chú ý là bất cứ khi nào truy vẫn một trường và trường đó

trả về đối tượng không thuộc các kiểu dữ liệu như vô hướng hoặc kiểu liệt kê, lập trình viên cần phải chỉ định đâu là đữ liệu cần lấy từ trường đó Ví dụ:

# INVALID: hero is not a

scalar, so fields are needed

hero

"message": "Field \"hero\" of

selection of subfields Did you mean

\"hero { }\"2",

Trang 35

Trong câu query trén, tac vu tim nap dt li€éu hero sé tra về một đối tượng thuộc kiểu

dữ liệu Character, bao gồm 2 trường là name và apppearsln Tuy nhiên, câu query trên

không hề chỉ ra đâu là trường cần lẫy dữ liệu Vì vậy, truy vẫn với câu g/ery trên là

không hợp lệ

Tương tự như vậy, nếu một trường được định nghĩa là thuộc kiểu đữ liệu vô hướng

thì việc truy vấn các trường con trong trường đó sẽ khiến cho truy vấn trở thành không hợp lệ:

{ "line": 4, "column": 10 }

]

}

] }

Điều cần lưu ý tiếp theo khi khởi tạo một truy vấn là chỉ có thể truy vấn dữ liệu

thuộc các trường đã được định nghĩa trong kiều một kiểu đữ liệu cụ thể Giả sử khi cần

truy vấn trường prừnaryFunction thuộc kiểu dữ liệu Droid Kiểu dữ liệu này sử dụng Interface Character nén sé co các trường đã được định nghĩa trong giao diện Characfer và có thêm trường prừnaryFunction được định nghĩa mới:

Trang 36

# INVALID: primaryFunction does

not exist on Character

ero

primaryFunction

\"Character\" Did you mean to use an inline fragment on \"Droid\"?",

{

"line": 5, "column": 5

Câu guery trên là gọi đến tác vụ tìm nạp hero trả về một đối tượng thuộc kiểu dữ

liệu Character Trường prữnaryFunction là một trường riêng của kiêu dữ liệu Droid va không phải là một trường được định nghĩa hợp lệ trong kiểu dữ liệu Characrer Do đó,

truy vấn với câu gwery trên là không hợp lệ Đề giải quyết vấn đề này, lập trình viên có

thé str dung Inline fragment dé viét cau query hop 1é

1.1.8 Thực thi (Execution)

Sau khi xác thực là hợp lệ, truy vẫn sẽ được máy chủ GraphQL thực thi và trả về

kết quả dựa theo hình dạng của truy vẫn Thông thường kết quả sẽ được trả về cho máy khách dưới dạng JSON

GraphQL sẽ không thể thực thi truy vấn nếu không có lược đồ được tạo thành bởi

hệ thống kiểu dữ liệu Mỗi trường trong truy vấn có thể được coi là một hàm hoặc một

phương thức của một kiểu dữ liệu nào đó Các trường trong một kiểu dữ liệu sẽ được bồ trợ bởi một hàm được gọi là hàm xử lý (resoi»er) Các hàm xử lý này sẽ do lập trình

viên tạo ra băng các ngôn ngữ lập trình Khi một trường được thực thi, máy chủ sẽ thực

hiện hàm xử lý tương ứng cho trường đó đề trả về dữ liệu cho máy khách

Nếu một trường trả về kiểu dữ liệu vô hướng nhu String hay Int thi quá trình thực

thi sẽ hoàn tất Tuy nhiên, nếu một trường trả về một đối tượng thì truy vẫn sẽ cần phải

chứa các trường thuộc kiểu đữ liệu của đối tượng đó Điều này sẽ lặp lại cho đến khi đạt được các giá trị vô hướng Việc thực thi các truy vẫn GraphQL, chỉ dừng lại khi tất

cả các trường đều nhận giá trị là một giá trị vô hướng

Ngày đăng: 11/06/2024, 23:14

w