GraphQL鎺ュ彛寮€鍙戝揩閫熷叆闂細鍛婂埆杩囧害鑾峰彇涓庝笉瓒宠幏鍙栫殑鏃朵唬鍦ㄤ紶缁熺殑RESTful API寮€鍙戜腑锛屼綘鏄惁鏇鹃亣鍒拌繃杩欐牱鐨勫洶鎵帮細涓轰簡鑾峰彇涓€涓敤鎴风殑鍩烘湰淇℃伅鍙婂叾鏈€杩戠殑涓夌瘒鏂囩珷锛屼綘闇€瑕佸厛璋冪敤/users/{id}鎺ュ彛鑾峰彇鐢ㄦ埛淇℃伅锛岀劧鍚庡啀璋冪敤/users/{id}/posts?limit3鑾峰彇鏂囩珷淇℃伅锛熸垨鑰呮洿绯熺硶鐨勬槸锛屽悗绔彁渚涗簡涓€涓€滃叏鑳解€濇帴鍙紝杩斿洖浜嗗ぇ閲忎綘涓嶉渶瑕佺殑瀛楁鏁版嵁锛岄€犳垚浜嗙綉缁滆祫婧愮殑娴垂锛?杩欏氨鏄疓raphQL瑕佽В鍐崇殑鏍稿績闂銆?浠€涔堟槸GraphQL锛?GraphQL鏄疐acebook浜?015骞村紑婧愮殑涓€绉岮PI鏌ヨ璇█鍜岃繍琛屾椂鐜銆傚畠涓嶆槸鏁版嵁搴撴煡璇㈣瑷€锛岃€屾槸API鏌ヨ璇█銆備笌RESTful API涓嶅悓锛孏raphQL鍏佽瀹㈡埛绔簿纭寚瀹氶渶瑕佺殑鏁版嵁缁撴瀯鍜屽瓧娈碉紝鏈嶅姟鍣ㄥ垯杩斿洖涓庤姹傚畬鍏ㄥ尮閰嶇殑鏁版嵁锛屼笉澶氫笉灏戙€?GraphQL鐨勬牳蹇冧紭鍔?1. 绮剧‘鑾峰彇鏁版嵁锛氬鎴风鍙互绮剧‘鎸囧畾闇€瑕佸摢浜涘瓧娈碉紝閬垮厤杩囧害鑾峰彇鎴栦笉瓒宠幏鍙?2. 鍗曚竴绔偣锛氭墍鏈夎姹傞兘鍙戦€佸埌鍚屼竴涓鐐癸紝绠€鍖栦簡API绠悊3. 寮虹被鍨嬬郴缁燂細GraphQL Schema鎻愪緵浜嗘槑纭殑绫诲瀷瀹氫箟锛屼究浜庡伐鍏烽摼鏀寔鍜岀被鍨嬫鏌?4. 瀹炴椂鏁版嵁鏀寔锛氶€氳繃璁㈤槄(subscriptions)鏀寔瀹炴椂鏁版嵁鏇存柊GraphQL鏍稿績姒傚康1. Schema锛堟ā寮忥級Schema鏄疓raphQL API鐨勬牳蹇冿紝瀹冨畾涔変簡API鐨勭被鍨嬬郴缁熷拰鑳藉姏銆係chema鐢辩被鍨嬪畾涔夌粍鎴愶紝鍏朵腑鏈€閲嶈鐨勬槸Query锛堟煡璇級銆丮utation锛堝彉鏇达級鍜孲ubscription锛堣闃咃級銆?graphqltype User {id: ID!name: String!email: String!posts: [Post!]!}type Post {id: ID!title: String!content: String!author: User!}type Query {user(id: ID!): Userposts(limit: Int): [Post!]!}type Mutation {createPost(title: String!, content: String!): Post!}2. Resolver锛堣В鏋愬櫒锛?瑙瀽鍣ㄦ槸瀹為檯鎵ц鏁版嵁鑾峰彇閫昏緫鐨勫嚱鏁般€傛瘡涓瓧娈甸兘鏈変竴涓搴旂殑瑙瀽鍣ㄣ€?javascriptconst resolvers {Query: {user: (parent, args, context, info) {return getUserById(args.id);},posts: (parent, args, context, info) {return getPosts(args.limit || 10);}},User: {posts: (parent, args, context, info) {return getPostsByUserId(parent.id);}}};3. Query锛堟煡璇級鏌ヨ鐢ㄤ簬鑾峰彇鏁版嵁锛岀被浼间簬RESTful API涓殑GET璇锋眰銆?graphqlquery GetUserWithPosts($userId: ID!) {user(id: $userId) {idnameemailposts(limit: 3) {idtitlecontent}}}4. Mutation锛堝彉鏇达級鍙樻洿鐢ㄤ簬淇敼鏁版嵁锛岀被浼间簬RESTful API涓殑POST銆丳UT銆丏ELETE璇锋眰銆?graphqlmutation CreatePost($title: String!, $content: String!) {createPost(title: $title, content: $content) {idtitlecontentauthor {idname}}}蹇€熷疄璺碉細鏋勫缓涓€涓畝鍗曠殑GraphQL API璁╂垜浠娇鐢∟ode.js鍜孉pollo Server蹇€熸瀯寤轰竴涓畝鍗曠殑GraphQL API銆?姝ラ1锛氬垵濮嬪寲椤圭洰bashmkdir graphql-apicd graphql-apinpm init -ynpm install apollo-server graphql姝ラ2锛氬垱寤哄熀纭€Schema鍜岃В鏋愬櫒javascript// index.jsconst { ApolloServer, gql } require(apollo-server);// 妯℃嫙鏁版嵁const users [{ id: 1, name: 寮犱笁, email: zhangsanexample.com },{ id: 2, name: 鏉庡洓, email: lisiexample.com }];const posts [{ id: 1, title: GraphQL鍏ラ棬, content: GraphQL鏄竴绉嶅己澶х殑API鏌ヨ璇█, authorId: 1 },{ id: 2, title: Node.js杩涢樁, content: 娣卞叆瀛︿範Node.js鐨勬牳蹇冩蹇?, authorId: 1 },{ id: 3, title: 鍓嶇寮€鍙戣秼鍔?, content: 2023骞村墠绔紑鍙戠殑鏂拌秼鍔?, authorId: 2 }];// 瀹氫箟Schemaconst typeDefs gqltype User {id: ID!name: String!email: String!posts: [Post!]!}type Post {id: ID!title: String!content: String!author: User!}type Query {users: [User!]!user(id: ID!): Userposts: [Post!]!post(id: ID!): Post}type Mutation {createUser(name: String!, email: String!): User!createPost(title: String!, content: String!, authorId: ID!): Post!};// 瀹氫箟瑙瀽鍣?const resolvers {Query: {users: () users,user: (parent, args) users.find(user user.id args.id),posts: () posts,post: (parent, args) posts.find(post post.id args.id)},User: {posts: (parent) posts.filter(post post.authorId parent.id)},Post: {author: (parent) users.find(user user.id parent.authorId)},Mutation: {createUser: (parent, args) {const newUser {id: String(users.length 1),name: args.name,email: args.email};users.push(newUser);return newUser;},createPost: (parent, args) {const newPost {id: String(posts.length 1),title: args.title,content: args.content,authorId: args.authorId};posts.push(newPost);return newPost;}}};// 鍒涘缓Apollo Server瀹炰緥const server new ApolloServer({typeDefs,resolvers});// 鍚姩鏈嶅姟鍣?server.listen().then(({ url }) {console.log(馃殌 Server ready at ${url});});姝ラ3锛氳繍琛屽苟娴嬭瘯APIbashnode index.js璁块棶 http://localhost:4000 鍗冲彲鎵撳紑GraphQL Playground锛岃繖鏄竴涓氦浜掑紡鐨凣raphQL IDE銆?姝ラ4锛氭墽琛屾煡璇?鍦≒layground涓皾璇曚互涓嬫煡璇細graphqlquery GetUsersWithPosts {users {idnameposts {idtitle}}}鎴栬€呭皾璇曞彉鏇存搷浣滐細graphqlmutation CreateNewPost {createPost(title: GraphQL瀹炴垬content: 閫氳繃瀹為檯妗堜緥瀛︿範GraphQLauthorId: 1) {idtitlecontentauthor {name}}}GraphQL鏈€浣冲疄璺?1. 鍚堢悊璁捐Schema锛氫粠涓氬姟闇€姹傚嚭鍙戯紝璁捐鍚堢悊鐨勭被鍨嬪拰鍏崇郴2. 閬垮厤N1鏌ヨ闂锛氫娇鐢―ataLoader绛夊伐鍏锋壒閲忓姞杞藉叧鑱旀暟鎹?3. 瀹炴柦鏉冮檺鎺у埗锛氬湪瑙瀽鍣ㄤ腑鍔犲叆璁よ瘉鍜屾巿鏉冮€昏緫4. 鎬ц兘鐩戞帶锛氱洃鎺ф煡璇㈡€ц兘鍜屽鏉傚害锛岄槻姝㈡伓鎰忓鏉傛煡璇?5. 鐗堟湰绠悊锛氶€氳繃娓愯繘寮廠chema婕旇繘鑰岄潪鐗堟湰鍙风鐞咥PI鍙樻洿GraphQL vs REST锛氫綍鏃堕€夋嫨锛?閫夋嫨GraphQL褰擄細- 闇€瑕佺伒娲荤殑鏁版嵁鑾峰彇锛岄伩鍏嶈繃搴﹁幏鍙栨垨涓嶈冻鑾峰彇- 鍓嶇闇€姹傚鍙橈紝闇€瑕佸揩閫熻凯浠?- 闇€瑕佸噺灏戠綉缁滆姹傛鏁?- 闇€瑕佸己绫诲瀷API鍜岃嚜鍔ㄦ枃妗敓鎴?閫夋嫨REST褰擄細- API缁撴瀯绠€鍗曞浐瀹?- 闇€瑕佸埄鐢℉TTP缂撳瓨鏈哄埗- 椤圭洰鍥㈤槦瀵筊EST鏇寸啛鎮?- 闇€瑕佺畝鍗曠殑鏂囦欢涓婁紶绛夋搷浣?鎬荤粨GraphQL浠〃浜咥PI璁捐鐨勬柊鑼冨紡锛屽畠閫氳繃璧嬩簣瀹㈡埛绔簿纭帶鍒舵暟鎹殑鑳藉姏锛岃В鍐充簡浼犵粺RESTful API鐨勮澶氱棝鐐广€傝櫧鐒跺涔犳洸绾跨浉瀵归櫋宄紝浣嗕竴鏃︽帉鎻★紝瀹冨皢鏋佸ぇ鍦版彁鍗囧墠鍚庣鍗忎綔鏁堢巼鍜岀敤鎴蜂綋楠屻€?鏃犺浣犳槸鍓嶇寮€鍙戣€呭笇鏈涜幏寰楁洿鐏垫椿鐨勬暟鎹幏鍙栬兘鍔涳紝杩樻槸鍚庣寮€鍙戣€呭笇鏈涙瀯寤烘洿楂樻晥鐨凙PI锛孏raphQL閮藉€煎緱浣犳姇鍏ユ椂闂村涔犮€備粠浠婂ぉ寮€濮嬶紝灏濊瘯鍦ㄤ綘鐨勪笅涓€涓」鐩腑寮曞叆GraphQL锛屼綋楠屽畠甯︽潵鐨勫彉闈╁惂锛?璁颁綇锛屾妧鏈€夊瀷姘歌繙鏈嶅姟浜庝笟鍔渶姹傘€侴raphQL涓嶆槸閾跺脊锛屼絾鍦ㄥ悎閫傜殑鍦烘櫙涓嬶紝瀹冪‘瀹炶兘甯︽潵鏄捐憲鐨勬晥鐜囨彁鍗囥€?