{"id":31376,"date":"2025-07-04T10:28:55","date_gmt":"2025-07-04T03:28:55","guid":{"rendered":"https:\/\/interdata.vn\/blog\/?p=31376"},"modified":"2025-07-04T16:10:41","modified_gmt":"2025-07-04T09:10:41","slug":"toi-uu-api-graphql","status":"publish","type":"post","link":"https:\/\/interdata.vn\/blog\/toi-uu-api-graphql\/","title":{"rendered":"10+ M\u1eb9o T\u1ed1i \u01afu API GraphQL D\u1ec5 B\u1ea3o Tr\u00ec, S\u1ea1ch &#038; T\u1ed1i \u01afu H\u00f3a"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-white ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">N\u1ed8I DUNG<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 eztoc-toggle-hide-by-default' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/interdata.vn\/blog\/toi-uu-api-graphql\/#Vi-sao-nen-toi-uu-API-GraphQL\" >V\u00ec sao n\u00ean t\u1ed1i \u01b0u API GraphQL?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/interdata.vn\/blog\/toi-uu-api-graphql\/#10-meo-toi-uu-API-GraphQL\" >10 m\u1eb9o t\u1ed1i \u01b0u API GraphQL<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/interdata.vn\/blog\/toi-uu-api-graphql\/#Thiet-ke-so-do-ranh-mach\" >Thi\u1ebft k\u1ebf s\u01a1 \u0111\u1ed3 r\u00e0nh m\u1ea1ch<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/interdata.vn\/blog\/toi-uu-api-graphql\/#Han-che-%E2%80%9Cdo-kho%E2%80%9D-cua-truy-van\" >H\u1ea1n ch\u1ebf &#8220;\u0111\u1ed9 kh\u00f3&#8221; c\u1ee7a truy v\u1ea5n<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/interdata.vn\/blog\/toi-uu-api-graphql\/#Phan-trang-thong-minh\" >Ph\u00e2n trang th\u00f4ng minh<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/interdata.vn\/blog\/toi-uu-api-graphql\/#Xu-ly-loi-chuyen-nghiep\" >X\u1eed l\u00fd l\u1ed7i chuy\u00ean nghi\u1ec7p<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/interdata.vn\/blog\/toi-uu-api-graphql\/#Quan-ly-phien-ban-API\" >Qu\u1ea3n l\u00fd phi\u00ean b\u1ea3n API<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/interdata.vn\/blog\/toi-uu-api-graphql\/#Luu-Cache-de-tang-toc\" >L\u01b0u Cache \u0111\u1ec3 t\u0103ng t\u1ed1c<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/interdata.vn\/blog\/toi-uu-api-graphql\/#Bao-mat-API-chac-chan\" >B\u1ea3o m\u1eadt API ch\u1eafc ch\u1eafn<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/interdata.vn\/blog\/toi-uu-api-graphql\/#Tai-lieu-day-du-la-chia-khoa\" >T\u00e0i li\u1ec7u \u0111\u1ea7y \u0111\u1ee7 l\u00e0 ch\u00eca kh\u00f3a<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/interdata.vn\/blog\/toi-uu-api-graphql\/#Giai-quyet-van-de-N1-Query\" >Gi\u1ea3i quy\u1ebft v\u1ea5n \u0111\u1ec1 N+1 Query<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/interdata.vn\/blog\/toi-uu-api-graphql\/#Theo-doi-va-toi-uu-hieu-suat-lien-tuc\" >Theo d\u00f5i v\u00e0 t\u1ed1i \u01b0u hi\u1ec7u su\u1ea5t li\u00ean t\u1ee5c<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<p>GraphQL \u0111ang d\u1ea7n tr\u1edf th\u00e0nh m\u1ed9t c\u00f4ng c\u1ee5 kh\u00f4ng th\u1ec3 thi\u1ebfu trong qu\u00e1 tr\u00ecnh x\u00e2y d\u1ef1ng API hi\u1ec7n \u0111\u1ea1i. Thay v\u00ec t\u1ea1o h\u00e0ng lo\u1ea1t endpoint cho t\u1eebng lo\u1ea1i d\u1eef li\u1ec7u ri\u00eang bi\u1ec7t nh\u01b0 REST, GraphQL cho ph\u00e9p b\u1ea1n truy v\u1ea5n nhi\u1ec1u d\u1eef li\u1ec7u kh\u00e1c nhau ch\u1ec9 th\u00f4ng qua m\u1ed9t endpoint duy nh\u1ea5t gi\u00fap \u1ee9ng d\u1ee5ng tr\u1edf n\u00ean g\u1ecdn g\u00e0ng, t\u1ed1i \u01b0u h\u01a1n v\u00e0 vi\u1ec7c truy xu\u1ea5t d\u1eef li\u1ec7u c\u0169ng nhanh ch\u00f3ng h\u01a1n r\u1ea5t nhi\u1ec1u. B\u00e0i vi\u1ebft n\u00e0y s\u1ebd chia s\u1ebb 10 m\u1eb9o quan tr\u1ecdng gi\u00fap b\u1ea1n <strong><a href=\"https:\/\/interdata.vn\/blog\/toi-uu-api-graphql\/\">t\u1ed1i \u01b0u API GraphQL<\/a><\/strong> s\u1ea1ch, hi\u1ec7u qu\u1ea3 v\u00e0 d\u1ec5 b\u1ea3o tr\u00ec v\u1ec1 l\u00e2u d\u00e0i.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Vi-sao-nen-toi-uu-API-GraphQL\"><\/span>V\u00ec sao n\u00ean t\u1ed1i \u01b0u API GraphQL?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u00c1p d\u1ee5ng \u0111\u00fang best practices kh\u00f4ng ch\u1ec9 l\u00e0 chuy\u1ec7n t\u1ed1i \u01b0u hi\u1ec7u su\u1ea5t, m\u00e0 c\u00f2n \u0111em l\u1ea1i nhi\u1ec1u gi\u00e1 tr\u1ecb thi\u1ebft th\u1ef1c kh\u00e1c:<\/p>\n<ul>\n<li><strong>Truy xu\u1ea5t d\u1eef li\u1ec7u \u0111\u00fang th\u1ee9 c\u1ea7n thi\u1ebft<\/strong>: Thay v\u00ec nh\u1eadn v\u1ec1 c\u1ea3 \u0111\u1ed1ng d\u1eef li\u1ec7u d\u01b0 th\u1eeba, ng\u01b0\u1eddi d\u00f9ng c\u00f3 th\u1ec3 ch\u1ecdn ch\u00ednh x\u00e1c th\u00f4ng tin h\u1ecd mu\u1ed1n \u2013 ti\u1ebft ki\u1ec7m t\u00e0i nguy\u00ean v\u00e0 t\u0103ng t\u1ed1c \u0111\u1ed9 x\u1eed l\u00fd.<\/li>\n<li><strong>L\u01b0\u1ee3c \u0111\u1ed3 (schema) r\u00f5 r\u00e0ng, d\u1ec5 qu\u1ea3n l\u00fd<\/strong>: M\u1ed9t schema r\u00f5 r\u00e0ng gi\u00fap \u0111\u1ed9i ng\u0169 d\u1ec5 ph\u00e1t tri\u1ec3n, b\u1ea3o tr\u00ec, \u0111\u1ed3ng th\u1eddi t\u1ea1o \u0111i\u1ec1u ki\u1ec7n h\u1ee3p t\u00e1c hi\u1ec7u qu\u1ea3 gi\u1eefa backend v\u00e0 frontend.<\/li>\n<li><strong>T\u00edch h\u1ee3p m\u01b0\u1ee3t v\u1edbi frontend hi\u1ec7n \u0111\u1ea1i<\/strong>: V\u1edbi nh\u1eefng c\u00f4ng c\u1ee5 &#8220;x\u1ecbn s\u00f2&#8221; nh\u01b0 Apollo v\u00e0 Relay, GraphQL d\u1ec5 d\u00e0ng h\u00f2a nh\u1eadp v\u00e0o c\u00e1c n\u1ec1n t\u1ea3ng front-end hi\u1ec7n \u0111\u1ea1i. Khi \u00e1p d\u1ee5ng best practices, b\u1ea1n kh\u00f4ng ch\u1ec9 &#8220;n\u00e2ng c\u1ea5p&#8221; hi\u1ec7u su\u1ea5t m\u00e0 c\u00f2n \u0111\u1ea3m b\u1ea3o code c\u1ee7a m\u00ecnh d\u1ec5 b\u1ea3o tr\u00ec v\u00e0 c\u00f3 th\u1ec3 m\u1edf r\u1ed9ng trong t\u01b0\u01a1ng lai.<\/li>\n<\/ul>\n<figure id=\"attachment_31379\" aria-describedby=\"caption-attachment-31379\" style=\"width: 800px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/interdata.vn\/blog\/wp-content\/uploads\/2025\/07\/Vi-sao-nen-tuan-thu-best-practices-khi-lam-viec-voi-GraphQL.jpg\" alt=\"V\u00ec sao n\u00ean tu\u00e2n th\u1ee7 best practices khi l\u00e0m vi\u1ec7c v\u1edbi GraphQL\" width=\"800\" height=\"500\" class=\"size-full wp-image-31379\" title=\"\" srcset=\"https:\/\/interdata.vn\/blog\/wp-content\/uploads\/2025\/07\/Vi-sao-nen-tuan-thu-best-practices-khi-lam-viec-voi-GraphQL.jpg 800w, https:\/\/interdata.vn\/blog\/wp-content\/uploads\/2025\/07\/Vi-sao-nen-tuan-thu-best-practices-khi-lam-viec-voi-GraphQL-300x188.jpg 300w, https:\/\/interdata.vn\/blog\/wp-content\/uploads\/2025\/07\/Vi-sao-nen-tuan-thu-best-practices-khi-lam-viec-voi-GraphQL-768x480.jpg 768w, https:\/\/interdata.vn\/blog\/wp-content\/uploads\/2025\/07\/Vi-sao-nen-tuan-thu-best-practices-khi-lam-viec-voi-GraphQL-750x469.jpg 750w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><figcaption id=\"caption-attachment-31379\" class=\"wp-caption-text\">V\u00ec sao n\u00ean tu\u00e2n th\u1ee7 best practices khi l\u00e0m vi\u1ec7c v\u1edbi GraphQL<\/figcaption><\/figure>\n<h2><span class=\"ez-toc-section\" id=\"10-meo-toi-uu-API-GraphQL\"><\/span>10 m\u1eb9o t\u1ed1i \u01b0u API GraphQL<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>D\u01b0\u1edbi \u0111\u00e2y l\u00e0 m\u1ed9t v\u00e0i &#8220;m\u1eb9o&#8221; hay m\u00e0 b\u1ea1n n\u00ean ghi nh\u1edb khi t\u1ed1i \u01b0u API GraphQL:<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Thiet-ke-so-do-ranh-mach\"><\/span>Thi\u1ebft k\u1ebf s\u01a1 \u0111\u1ed3 r\u00e0nh m\u1ea1ch<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>S\u01a1 \u0111\u1ed3 r\u00f5 r\u00e0ng s\u1ebd gi\u00fap code c\u1ee7a b\u1ea1n d\u1ec5 &#8220;ch\u0103m s\u00f3c&#8221; h\u01a1n. H\u00e3y b\u1eaft \u0111\u1ea7u b\u1eb1ng c\u00e1ch \u0111\u1ecbnh ngh\u0129a c\u00e1c ki\u1ec3u d\u1eef li\u1ec7u, truy v\u1ea5n v\u00e0 thay \u0111\u1ed5i d\u1eef li\u1ec7u (mutations) m\u1ed9t c\u00e1ch c\u00f3 h\u1ec7 th\u1ed1ng. V\u00ed d\u1ee5: <code>$type User { id: ID! name: String! email: String! }$<\/code>. \u0110\u1eb7t t\u00ean th\u1eadt d\u1ec5 hi\u1ec3u v\u00e0 th\u00eam ch\u00fa th\u00edch cho nh\u1eefng ph\u1ea7n ph\u1ee9c t\u1ea1p \u0111\u1ec3 ai \u0111\u1ecdc c\u0169ng hi\u1ec3u.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Han-che-%E2%80%9Cdo-kho%E2%80%9D-cua-truy-van\"><\/span>H\u1ea1n ch\u1ebf &#8220;\u0111\u1ed9 kh\u00f3&#8221; c\u1ee7a truy v\u1ea5n<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>\u0110\u1ec3 tr\u00e1nh t\u00ecnh tr\u1ea1ng truy v\u1ea5n qu\u00e1 ph\u1ee9c t\u1ea1p l\u00e0m &#8220;\u0111\u01a1&#8221; m\u00e1y ch\u1ee7, b\u1ea1n n\u00ean \u00e1p d\u1ee5ng c\u00e1c bi\u1ec7n ph\u00e1p gi\u1edbi h\u1ea1n \u0111\u1ed9 ph\u1ee9c t\u1ea1p. H\u00e3y d\u00f9ng th\u01b0 vi\u1ec7n \u0111\u1ec3 ph\u00e2n t\u00edch \u0111\u1ed9 ph\u1ee9c t\u1ea1p v\u00e0 \u0111\u1eb7t ra gi\u1edbi h\u1ea1n v\u1ec1 \u0111\u1ed9 s\u00e2u c\u0169ng nh\u01b0 k\u00edch th\u01b0\u1edbc truy v\u1ea5n: <code>$const { createComplexityLimitRule } = require('graphql-query-complexity');$<\/code>.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Phan-trang-thong-minh\"><\/span>Ph\u00e2n trang th\u00f4ng minh<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Khi ph\u1ea3i x\u1eed l\u00fd l\u01b0\u1ee3ng d\u1eef li\u1ec7u &#8220;kh\u1ee7ng&#8221;, thay v\u00ec tr\u1ea3 v\u1ec1 t\u1ea5t c\u1ea3, h\u00e3y \u00e1p d\u1ee5ng ph\u00e2n trang \u0111\u1ec3 mang l\u1ea1i tr\u1ea3i nghi\u1ec7m t\u1ed1t h\u01a1n cho ng\u01b0\u1eddi d\u00f9ng: <code>$query { users(first: 10) { edges { node { id name } } } }$<\/code>.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Xu-ly-loi-chuyen-nghiep\"><\/span>X\u1eed l\u00fd l\u1ed7i chuy\u00ean nghi\u1ec7p<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Vi\u1ec7c x\u1eed l\u00fd l\u1ed7i &#8220;chu\u1ea9n ch\u1ec9nh&#8221; c\u1ef1c k\u1ef3 quan tr\u1ecdng cho tr\u1ea3i nghi\u1ec7m ng\u01b0\u1eddi d\u00f9ng. Thay v\u00ec \u0111\u1ec3 l\u1ed9 th\u00f4ng tin nh\u1ea1y c\u1ea3m, h\u00e3y \u0111\u01b0a ra c\u00e1c th\u00f4ng b\u00e1o l\u1ed7i chung chung nh\u01b0ng c\u00f3 m\u00e3 tr\u1ea1ng th\u00e1i r\u00f5 r\u00e0ng: <code>$throw new ApolloError('User not found', 'USER_NOT_FOUND');$<\/code>.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Quan-ly-phien-ban-API\"><\/span>Qu\u1ea3n l\u00fd phi\u00ean b\u1ea3n API<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>D\u00f9 GraphQL khuy\u1ebfn kh\u00edch m\u1ed9t l\u01b0\u1ee3c \u0111\u1ed3 th\u1ed1ng nh\u1ea5t, vi\u1ec7c qu\u1ea3n l\u00fd phi\u00ean b\u1ea3n v\u1eabn c\u1ea7n thi\u1ebft khi c\u00f3 nh\u1eefng thay \u0111\u1ed5i l\u1edbn. H\u00e3y \u00e1p d\u1ee5ng c\u00e1c ph\u01b0\u01a1ng ph\u00e1p kh\u00f4ng l\u00e0m \u1ea3nh h\u01b0\u1edfng \u0111\u1ebfn l\u01b0\u1ee3c \u0111\u1ed3 hi\u1ec7n t\u1ea1i nh\u01b0ng v\u1eabn gi\u1edbi thi\u1ec7u \u0111\u01b0\u1ee3c t\u00ednh n\u0103ng m\u1edbi, v\u00ed d\u1ee5: <code>$type UserV2 { id: ID! name: String! email: String! age: Int! }$<\/code>.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Luu-Cache-de-tang-toc\"><\/span>L\u01b0u Cache \u0111\u1ec3 t\u0103ng t\u1ed1c<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>S\u1eed d\u1ee5ng b\u1ed9 nh\u1edb \u0111\u1ec7m (cache) c\u00f3 th\u1ec3 gi\u00fap gi\u1ea3m th\u1eddi gian ph\u1ea3n h\u1ed3i b\u1eb1ng c\u00e1ch l\u01b0u tr\u1eef k\u1ebft qu\u1ea3 c\u1ee7a c\u00e1c truy v\u1ea5n &#8220;ng\u1ed1n&#8221; t\u00e0i nguy\u00ean. C\u00e1c c\u00f4ng c\u1ee5 nh\u01b0 Apollo Client c\u00f3 th\u1ec3 t\u1ef1 \u0111\u1ed9ng l\u01b0u cache, nh\u01b0ng b\u1ea1n c\u1ea7n ch\u1eafc ch\u1eafn c\u1ea5u h\u00ecnh \u0111\u00fang: <code>$const client = new ApolloClient({ cache: new InMemoryCache() });$<\/code>.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Bao-mat-API-chac-chan\"><\/span>B\u1ea3o m\u1eadt API ch\u1eafc ch\u1eafn<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Tri\u1ec3n khai x\u00e1c th\u1ef1c v\u00e0 ph\u00e2n quy\u1ec1n \u0111\u1ec3 b\u1ea3o v\u1ec7 API c\u1ee7a b\u1ea1n. S\u1eed d\u1ee5ng c\u00e1c ph\u1ea7n m\u1ec1m trung gian nh\u01b0 graphql-shield \u0111\u1ec3 \u0111i\u1ec1u ch\u1ec9nh quy\u1ec1n truy c\u1eadp \u1edf c\u1ea5p \u0111\u1ed9 tr\u01b0\u1eddng: <code>$const permissions = shield({ Query: { users: isAuthenticated }, });$<\/code>.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Tai-lieu-day-du-la-chia-khoa\"><\/span>T\u00e0i li\u1ec7u \u0111\u1ea7y \u0111\u1ee7 l\u00e0 ch\u00eca kh\u00f3a<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Ngo\u00e0i vi\u1ec7c d\u00f9ng h\u1ec7 th\u1ed1ng ki\u1ec3u c\u1ee7a GraphQL \u0111\u1ec3 ghi l\u1ea1i t\u00e0i li\u1ec7u, vi\u1ec7c cung c\u1ea5p th\u00eam c\u00e1c t\u00e0i li\u1ec7u h\u01b0\u1edbng d\u1eabn c\u1ee5 th\u1ec3 s\u1ebd gi\u00fap ng\u01b0\u1eddi d\u00f9ng khai th\u00e1c t\u1ed1i \u0111a kh\u1ea3 n\u0103ng c\u1ee7a API. B\u1ea1n c\u00f3 th\u1ec3 d\u00f9ng c\u00e1c c\u00f4ng c\u1ee5 nh\u01b0 GraphiQL ho\u1eb7c Apollo Studio \u0111\u1ec3 t\u1ea1o t\u00e0i li\u1ec7u m\u1ed9t c\u00e1ch d\u1ec5 d\u00e0ng.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Giai-quyet-van-de-N1-Query\"><\/span>Gi\u1ea3i quy\u1ebft v\u1ea5n \u0111\u1ec1 N+1 Query<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>V\u1ea5n \u0111\u1ec1 N+1 Query x\u1ea3y ra khi d\u1eef li\u1ec7u li\u00ean quan b\u1ecb l\u1ea5y t\u1eebng ph\u1ea7n ri\u00eang bi\u1ec7t, l\u00e0m gi\u1ea3m hi\u1ec7u su\u1ea5t. S\u1eed d\u1ee5ng c\u00e1c c\u00f4ng c\u1ee5 x\u1eed l\u00fd h\u00e0ng lo\u1ea1t nh\u01b0 DataLoader gi\u00fap gi\u1ea3m thi\u1ec3u t\u00ecnh tr\u1ea1ng n\u00e0y: <code>$const loader = new DataLoader(keys =&gt; batchLoadFn(keys));$<\/code>.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Theo-doi-va-toi-uu-hieu-suat-lien-tuc\"><\/span>Theo d\u00f5i v\u00e0 t\u1ed1i \u01b0u hi\u1ec7u su\u1ea5t li\u00ean t\u1ee5c<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Vi\u1ec7c theo d\u00f5i hi\u1ec7u su\u1ea5t c\u1ee7a c\u00e1c truy v\u1ea5n GraphQL r\u1ea5t quan tr\u1ecdng \u0111\u1ec3 ph\u00e1t hi\u1ec7n nh\u1eefng \u0111i\u1ec3m &#8220;ngh\u1ebdn&#8221;. K\u1ebft h\u1ee3p c\u00e1c gi\u1ea3i ph\u00e1p gi\u00e1m s\u00e1t gi\u00fap b\u1ea1n c\u00f3 c\u00e1i nh\u00ecn s\u00e2u s\u1eafc v\u1ec1 th\u1eddi gian th\u1ef1c hi\u1ec7n v\u00e0 l\u1ed7i. Apollo Engine l\u00e0 m\u1ed9t c\u00f4ng c\u1ee5 h\u1eefu \u00edch \u0111\u1ec3 cung c\u1ea5p th\u00f4ng tin chi ti\u1ebft v\u1ec1 hi\u1ec7u su\u1ea5t c\u1ee7a API.<\/p>\n<p>\u00c1p d\u1ee5ng nh\u1eefng best practices tr\u00ean v\u00e0o quy tr\u00ecnh ph\u00e1t tri\u1ec3n GraphQL kh\u00f4ng ch\u1ec9 gi\u00fap b\u1ea1n x\u00e2y d\u1ef1ng API hi\u1ec7u qu\u1ea3 m\u00e0 c\u00f2n \u0111\u1ea3m b\u1ea3o code c\u00f3 th\u1ec3 m\u1edf r\u1ed9ng v\u00e0 b\u1ea3o tr\u00ec thu\u1eadn l\u1ee3i. Khi ch\u00fa \u00fd \u0111\u1ebfn vi\u1ec7c thi\u1ebft k\u1ebf, x\u1eed l\u00fd l\u1ed7i v\u00e0 t\u1ed1i \u01b0u h\u00f3a, b\u1ea1n s\u1ebd t\u1ea1o ra c\u00e1c API \u0111\u1ee7 s\u1ee9c &#8220;c\u00e2n&#8221; \u0111a d\u1ea1ng c\u00e1c t\u00ecnh hu\u1ed1ng s\u1eed d\u1ee5ng.<\/p>\n<p>GraphQL mang \u0111\u1ebfn nhi\u1ec1u l\u1ee3i th\u1ebf, v\u00e0 b\u1eb1ng c\u00e1ch \u00e1p d\u1ee5ng nh\u1eefng th\u1ef1c h\u00e0nh t\u1ed1t nh\u1ea5t, b\u1ea1n c\u00f3 c\u01a1 h\u1ed9i t\u1ed1i \u01b0u h\u00f3a c\u00f4ng ngh\u1ec7 m\u1ea1nh m\u1ebd n\u00e0y nh\u1eb1m mang l\u1ea1i tr\u1ea3i nghi\u1ec7m tuy\u1ec7t v\u1eddi nh\u1ea5t cho ng\u01b0\u1eddi d\u00f9ng.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>GraphQL \u0111ang d\u1ea7n tr\u1edf th\u00e0nh m\u1ed9t c\u00f4ng c\u1ee5 kh\u00f4ng th\u1ec3 thi\u1ebfu trong qu\u00e1 tr\u00ecnh x\u00e2y d\u1ef1ng API hi\u1ec7n \u0111\u1ea1i. Thay v\u00ec t\u1ea1o h\u00e0ng lo\u1ea1t endpoint cho t\u1eebng lo\u1ea1i d\u1eef li\u1ec7u ri\u00eang bi\u1ec7t nh\u01b0 REST, GraphQL cho ph\u00e9p b\u1ea1n truy v\u1ea5n nhi\u1ec1u d\u1eef li\u1ec7u kh\u00e1c nhau ch\u1ec9 th\u00f4ng qua m\u1ed9t endpoint duy nh\u1ea5t gi\u00fap \u1ee9ng d\u1ee5ng<\/p>\n","protected":false},"author":11,"featured_media":31380,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[140],"tags":[],"class_list":["post-31376","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-lap-trinh"],"_links":{"self":[{"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/posts\/31376","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/comments?post=31376"}],"version-history":[{"count":7,"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/posts\/31376\/revisions"}],"predecessor-version":[{"id":31419,"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/posts\/31376\/revisions\/31419"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/media\/31380"}],"wp:attachment":[{"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/media?parent=31376"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/categories?post=31376"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/tags?post=31376"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}