GraphQL - Truy vấn
Hoạt động GraphQL có thể là hoạt động đọc hoặc ghi. Truy vấn GraphQL được sử dụng để đọc hoặc tìm nạp các giá trị trong khi một đột biến được sử dụng để ghi hoặc đăng các giá trị. Trong cả hai trường hợp, hoạt động là một chuỗi đơn giản mà máy chủ GraphQL có thể phân tích cú pháp và phản hồi với dữ liệu ở định dạng cụ thể. Định dạng phản hồi phổ biến thường được sử dụng cho các ứng dụng web và di động là JSON.
Cú pháp để xác định một truy vấn như sau:
//syntax 1
query query_name{ someField }
//syntax 2
{ someField }
Sau đây là một ví dụ về truy vấn:
//query with name myQuery
query myQuery{
greeting
}
// query without any name
{
greeting
}
Rõ ràng từ ví dụ trên rằng từ khóa truy vấn là tùy chọn.
Truy vấn GraphQL giúp giảm tải quá nhiều dữ liệu. Không giống như API Restful, GraphQL cho phép người dùng hạn chế các trường nên được tải từ máy chủ. Điều này có nghĩa là các truy vấn nhỏ hơn và lưu lượng truy cập qua mạng ít hơn; do đó làm giảm thời gian phản hồi.
Hình minh họa 1 - Mô hình sinh viên truy vấn với trường tùy chỉnh
Trong ví dụ này, chúng ta có một nhóm sinh viên được lưu trữ trong một tệp json. Mỗi mô hình sinh viên có các trường như firstName, lastName và id nhưng không có fullName. Ở đây, chúng ta sẽ thảo luận về cách thực hiện truy vấn để lấy ra fullName của tất cả học sinh. Đối với điều này, chúng ta cần tạo trường fullName trong cả hai trình phân giải lược đồ.
Hãy để chúng tôi xem cách thực hiện minh họa này bằng các bước dưới đây -
Bước 1 - Tải xuống và cài đặt các phụ thuộc bắt buộc cho dự án
Tạo một thư mục có tên query-app. Thay đổi thư mục của bạn thànhquery-apptừ thiết bị đầu cuối. Sau đó, hãy làm theo các bước từ 3 đến 5 được giải thích trong chương Thiết lập Môi trường.
Bước 2 - Tạo một lược đồ
Thêm vào schema.graphql tệp trong ứng dụng truy vấn thư mục dự án và thêm mã sau:
type Query {
greeting:String
students:[Student]
studentById(id:ID!):Student
}
type Student {
id:ID!
firstName:String
lastName:String
fullName:String
}
Lưu ý rằng không có trường fullName trongstudents.jsontập tin. Tuy nhiên, chúng ta cần lấy tên đầy đủ của học sinh thông qua một truy vấn. Các FullName , trong trường hợp này sẽ là một lĩnh vực tùy chỉnh mà không có sẵn với nguồn dữ liệu.
Bước 3 - Tạo trình phân giải
Tạo một tệp resolvers.js trong thư mục dự án và thêm mã sau:
const db = require('./db')
const Query = {
//resolver function for greeting
greeting:() => {
return "hello from TutorialsPoint !!!"
},
//resolver function for students returns list
students:() => db.students.list(),
//resolver function for studentbyId
studentById:(root,args,context,info) => {
//args will contain parameter passed in query
return db.students.get(args.id);
}
}
//for each single student object returned,resolver is invoked
const Student = {
fullName:(root,args,context,info) => {
return root.firstName+":"+root.lastName
}
}
module.exports = {Query,Student}
Bước 4 - Chạy ứng dụng
Tạo một server.jstập tin. Tham khảo bước 8 trong Chương Thiết lập Môi trường. Thực hiện lệnh npm start trong terminal. Máy chủ sẽ hoạt động trên cổng 9000. Ở đây, chúng tôi sử dụng GraphiQL làm máy khách để kiểm tra ứng dụng.
Mở trình duyệt và nhập URL http://localhost:9000/graphiql. Nhập truy vấn sau vào trình soạn thảo -
{
students{
id
fullName
}
}
Phản hồi cho truy vấn được đưa ra dưới đây:
{
"data": {
"students": [
{
"id": "S1001",
"fullName": "Mohtashim:Mohammad"
},
{
"id": "S1002",
"fullName": "Kannan:Sudhakaran"
},
{
"id": "S1003",
"fullName": "Kiran:Panigrahi"
}
]
}
}
Tạo một server.js và thêm mã sau -
const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const db = require('./db');
const port = 9000;
const app = express();
//loading type definitions from schema file
const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
//loading resolvers
const resolvers = require('./resolvers')
//binding schema and resolver
const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})
//enabling cross domain calls and form post
app.use(cors(), bodyParser.json());
//enabling routes
const {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))
//registering port
app.listen(port, () => console.info(`Server started on port ${port}`));
Thực hiện lệnh npm start trong terminal. Máy chủ sẽ hoạt động trên cổng 9000. Ở đây, chúng tôi sử dụng GraphiQL làm máy khách để kiểm tra ứng dụng.
Mở trình duyệt và nhập URL http://localhost:9000/graphiql. Nhập truy vấn sau vào trình soạn thảo -
{
students{
id
fullName
}
}
Phản hồi cho truy vấn được đưa ra dưới đây:
{
"data": {
"students": [
{
"id": "S1001",
"fullName": "Mohtashim:Mohammad"
},
{
"id": "S1002",
"fullName": "Kannan:Sudhakaran"
},
{
"id": "S1003",
"fullName": "Kiran:Panigrahi"
}
]
}
}
Hình minh họa 2 - Truy vấn lồng nhau
Hãy để chúng tôi tạo một truy vấn lồng nhau để tìm nạp thông tin chi tiết về sinh viên và thông tin chi tiết về trường đại học của họ. Chúng tôi sẽ làm việc với cùng một thư mục dự án.
Bước 1 - Chỉnh sửa lược đồ
Tệp giản đồ đã có trường sinh viên . Hãy để chúng tôi thêm một trường cao đẳng thực địa và xác định loại của nó.
type College {
id:ID!
name:String
location:String
rating:Float
}
type Student {
id:ID!
firstName:String
lastName:String
fullName:String
college:College
}
Bước 2 - Sửa đổi giải quyết.js
Chúng ta cần thêm một hàm phân giải cao đẳng như bên dưới. Hàm phân giải cao đẳng sẽ được thực thi cho mỗi đối tượng sinh viên được trả về. Tham số gốc của trình giải quyết trong trường hợp này sẽ chứa học sinh .
const Student = {
fullName:(root,args,context,info) => {
return root.firstName+":"+root.lastName
},
college:(root) => {
return db.colleges.get(root.collegeId);
}
}
module.exports = {Query,Student}
Trình giải quyết trả về đại học của mỗi học sinh bằng cách gọi phương thức get của bộ sưu tập đại học và vượt qua collegeId . Chúng tôi có mối quan hệ liên kết giữa Sinh viên và Cao đẳng thông qua collegeId .
Bước 3 - Kiểm tra ứng dụng
Mở cửa sổ đầu cuối và điều hướng đến thư mục dự án. Gõ lệnh -npm start. Khởi chạy trình duyệt và nhập URLhttp://localhost:9000/graphiql.
Nhập truy vấn sau vào cửa sổ GraphiQL -
{
students{
id
firstName
college {
id
name
location
rating
}
}
}
Câu trả lời cho truy vấn như được đưa ra bên dưới:
{
"data": {
"students": [
{
"id": "S1001",
"firstName": "Mohtashim",
"college": {
"id": "col-102",
"name": "CUSAT",
"location": "Kerala",
"rating": 4.5
}
},
{
"id": "S1002",
"firstName": "Kannan",
"college": {
"id": "col-101",
"name": "AMU",
"location": "Uttar Pradesh",
"rating": 5
}
},
{
"id": "S1003",
"firstName": "Kiran",
"college": {
"id": "col-101",
"name": "AMU",
"location": "Uttar Pradesh",
"rating": 5
}
}
]
}
}
Biến truy vấn là gì?
Nếu truy vấn có một số giá trị động cần được chuyển, thì hãy biểu diễn các giá trị động này bằng cách sử dụng các biến. Do đó, truy vấn có thể được sử dụng lại bởi các ứng dụng khách.
Hình minh họa
Hãy để chúng tôi tạo một ứng dụng đơn giản để hiểu biến truy vấn.
Bước 1 - Chỉnh sửa tệp lược đồ
Thêm trường sayHello nhận tham số chuỗi và trả về một chuỗi. Các giá trị tên sẽ là động trong ứng dụng khách.
type Query {
sayHello(name:String!):String
}
Bước 2 - Chỉnh sửa tệp Resolutionver.js
Thêm trình phân giải sayHello nhận tham số như bên dưới:
sayHello:(root,args,context,info) => `Hi ${args.name} GraphQL server says Hello to you!!`
Bước 3 - Khai báo biến truy vấn trong GraphiQL
Một biến được khai báo với $ theo sau là tên của biến. Ví dụ: $ myname_Variable.
Khi $ myname_Variable được khai báo, nó phải được sử dụng với cú pháp truy vấn được đặt tên. Truy vấn, myQuery nhận giá trị chuỗi và chuyển nó đến sayHello như hình dưới đây:
query myQuery($myname_Variable:String!) {
sayHello(name:$myname_Variable)
}
Đặt giá trị cho $ myname_Variable dưới dạng đối tượng JSON trong phần Biến truy vấn của máy khách GraphiQL.
{
"myname_Variable": "Mohtashim"
}
Đầu ra của đoạn mã trên như sau:
{
"data": {
"sayHello": "Hi Mohtashim GraphQL server says Hello to you!!"
}
}
Cách sử dụng Biến truy vấn với Enum
Hãy để chúng tôi xem cách sử dụng biến truy vấn khi tham số trường là enum type.
Bước 1 - Chỉnh sửa tệp schema.graphql
enum ColorType {
RED
BLUE
GREEN
}
type Query {
setFavouriteColor(color:ColorType):String
}
Hàm setFavouriteColor nhận enum làm đầu vào và trả về một giá trị chuỗi.
Bước 2 - Chỉnh sửa tệp Resolutionvers.js
Hàm phân giải setFavouriteColor có gốc và args . Giá trị enum được truyền cho hàm trong thời gian chạy có thể được truy cập thông qua tham số args.
setFavouriteColor:(root,args) => {
return "Your Fav Color is :"+args.color;
}
Bước 3 - Khai báo một biến truy vấn trong GraphiQL
Truy vấn được đặt tên query_to_setColortrong đó có một biến tên color_variable của ColorType. Biến này được chuyển cho phương thức setFavouriteColor.
query query_to_setColor($color_variable:ColorType) {
setFavouriteColor(color:$color_variable)
}
In the query variable section of GraphiQL, type the following code −
{
"color_variable":"RED"
}
The response is shown below −
{
"data": {
"setFavouriteColor": "Your Fav Color is: RED"
}
}