Những điều bạn cần phải biết về GraphQL – Công nghệ mới cho web developer
Nếu bạn cũng như tôi, một tín đồ về lập trình thì hẳn bạn cũng trải qua 3 khung cảm xúc mỗi khi nghe tin công nghệ mới xuất hiện: 1/ Chán nản: Lại thêm một JavaScript library?! Sao không xài jQuery quách cho rồi? 2/ Quan tâm: Hmm, cũng được đấy, để check thử cái ...
Nếu bạn cũng như tôi, một tín đồ về lập trình thì hẳn bạn cũng trải qua 3 khung cảm xúc mỗi khi nghe tin công nghệ mới xuất hiện:
1/ Chán nản:
Lại thêm một JavaScript library?! Sao không xài jQuery quách cho rồi?
2/ Quan tâm:
Hmm, cũng được đấy, để check thử cái library mới này xem sao?
3/ Hoảng loạn:
Thôi chết rồi, hoặc là phải biết xài thằng này không thì chỉ có nước hửi khói tụi khác!
Cách để giữ bạn không phải phát điên lên khi trải qua 3 giai đoạn trên là phải học được những thứ mới mẻ ngay giữa giai đoạn 2 và 3, khi mà bạn đã có hứng thú về nó nhưng công nghệ vẫn còn mới mẻ chưa được biết đến nhiều.
Vì thế mà bây giờ là thời điểm hoàn hảo để học về GraphQL mà mọi người luôn bàn tàn gần đây.
Tóm lại, GraphQL là một cú pháp mô tả cách yêu cầu lấy dữ liệu, và thường được dùng để load data từ một server cho client. GraphQL bao gồm 3 điểm đặc trưng sau:
- Nó cho phép client xác định chính xác những gì dữ liệu họ cần.
- Nó làm cho việc tổng hợp dữ liệu từ nhiều nguồn dễ dàng hơn.
- Nó sử dụng một type system để mô tả dữ liệu
Thế thì GraphQL hoạt động như thế nào? ta dùng nó như thế nào?
GraphQL bắt đầu từ ông lớn Facebook, thế nhưng ngay cả những app đơn giản đôi khi vẫn gặp phải trường hợp “nghẽn cổ chai” do sự hạn chế của REST APIs.
Thí dụ bạn muốn hiển thị một list ‘posts’, và ở dưới mỗi ‘post’ là một list ‘like’, bao gồm cả tên người dùng và avatar. Cách giải quyết đơn giản là thay đổi API của ‘posts’ để nó bao gồm a ‘like’ array chứa thông tin về người dùng.
Thế nhưng khi làm như vậy cho các app mobile thì bạn sẽ phát hiện ra tốc độ của chúng chạy quá chậm. Vì thế mà giờ đây bạn sẽ cần tới 2 endpoints, một với likesvà một thiếu chúng.
Giờ thì còn có thêm một vấn đề khác xuất hiện: trong khi postsđược lưu trữ trong một MySQL database thì likes lại được lưu tại Redis store! Bạn biết mình phải làm gì trong trường hợp nào không?
Mở rộng vấn đề trên ra với việc Facebook phải quản lí vô số data source và API clients thì cũng là điều dễ hiểu khi REST APIs bị đánh giá là cũ kĩ bởi những hạn chế của nó.
Giải pháp mà Facebook đưa ra đến từ một ý tưởng rất đơn giản: Thay vì có đến hàng tá “endpoint” ngu ngốc, sao lại không dùng chỉ một “endpoint” thông minh với khả năng tiếp thu những Query phức tạp rồi đưa ra output data với loại type tùy theo yêu cầu của client.
Thế tế mà nói, GraphQL như là một layer nằm giữa client và data source, sau khi nhận yêu cầu của client thì nó sẽ kiếm những thông tin cần từ các data source và đưa lại cho client theo format họ muốn. Vẫn chưa hiểu? Thế thì đến lúc dùng ví dụ ẩn dụ rồi đây!
Như bạn thấy đấy, REST model cũ giống y như việc bạn đặt cái bánh Pizza, rồi gọi ship hàng online và kêu bên tiệm giặt ủi đem đồ đến cho bạn. Tất cả diễn ra với 3 cuộc gọi và 3 cửa hàng.
GraphQL mặt khác lại giống như là thư kí riêng của bạn vậy: Sau khi bạn đưa địa chỉ của 3 cửa hàng và nói yêu cầu của bạn thì GraphQL sẽ làm hết mọi chuyện còn lại trong khi bạn chỉ việc chờ chúng được chuyển đến cho mình.
Nói cách khác GraphQL tạo ra một ngôn ngữ chuẩn (standard language) để thực hiện những công việc này.
GraphQL API được tạo ra từ 3 phần chính: schema, queries, và resolvers
Queries
Những yêu cầu bạn đặt ra cho thư kí của mình, GraphQL, được gọi là query và nó giống như thế này:
1 2 3 4 5 |
query { stuff } |
Chúng ta tuyên bố một ‘query’ mới sử dụng keyword query , và đặt tên cho field đó là stuff. Điều thú vị của GraphQL query là có support các nested fields. Thế nên chúng ta có thể đi sâu vào hơn:
1 2 3 4 5 6 7 8 9 |
query { stuff { eggs shirt pizza } } |
Như bạn thấy đấy, client khi đưa ra những yêu cầu và tạo ra query sẽ không cần lo data đến từ source nào. Chỉ việc hỏi và GraphQL server sẽ lo hết mọi thứ khác.
Cũng đáng lưu ý là việc các query field còn có khả năng chỉ đến các array
1 2 3 4 5 6 7 8 9 10 11 12 13 |
query { posts { # this is an array title body author { # we can go deeper! name avatarUrl profileUrl } } } |
Query field còn support cả argument. Nếu bạn muốn đưa ra một post riêng, thì chỉ cần thêm id argument cho post field.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
query { post(id: "123foo"){ title body author{ name avatarUrl profileUrl } } } |
Cuối cùng, nếu bạn còn muốn id argument đó đặc biệt hơn, bạn có thể tạo ra một variable và tái sử dụng chúng bên trong query (nhớ là ta phải đặt tên cái query đó luôn)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
query getMyPost($id: String) { post(id: $id){ title body author{ name avatarUrl profileUrl } } } |
Một cách thực hành khá tốt là sử dụng GitHub’s GraphQL API Explorer. Hãy thử query sau:
1 2 3 4 5 6 7 8 |
<strong class="markup--strong markup--pre-strong">query</strong> { repository(owner: "graphql", name: "graphql-js"){ name description } } |
Bạn sẽ thấy rằng việc bạn thử đặt tên cho một field ở bên dưới description, IDE sẽ tự động gợi ý cho bạn những tên field có sẵn hoặc tự tạo bởi chính GraphQL API ! Khá hay đúng không?
Resolvers
Cho dù có là thư ký giỏi nhất quả đất cũng không thể đi lấy quần áo cho bạn nếu không có địa chỉ của tiệm giặt đồ.
Tương tự vậy, GraphQL server sẽ không biết phải làm gì với query bạn đưa ra trừ khi nó biết được resolver.
Resolver nói cho GraphQL biết nơi và cách thức để lấy data cần thiết cho field của query mà bạn yêu cầu. Sau đây là một resolver cho field post ở trên (sử dụng Apollo’s GraphQL-Tools schema generator):
1 2 3 4 5 6 7 |
Query: { post(root, args) { return Posts.find({ id: args.id }); } } |
Ta đặt resolver ngay trong Query bởi vì ta muốn query cho post ngay lập tức. Tuy nhiên, bạn vẫn có thể dùng resolver trong sub-field, như author field của post
1 2 3 4 5 6 7 8 9 10 11 12 |
Query: { post(root, args) { return Posts.find({ id: args.id }); } }, Post: { author(post) { return Users.find({ id: post.authorId}) } } |
Nhớ lưu ý rằng resolver sẽ không bị giới hạn bởi trong số lượng thông tin được đưa về nên bạn sẽ muốn thêm commentsCount cho Post type:
1 2 3 4 5 6 7 8 9 10 |
Post: { author(post) { return Users.find({ id: post.authorId}) }, commentsCount(post) { return Comments.find({ postId: post.id}).count() } } |
Điều quan trong bạn cần hiểu ở đây là với GraphQL, API schema của bạn và database schema sẽ bị chia ra riêng biệt. Nói cách khác, có thể sẽ không có bất kì author và commentsCount nào trong database của mình nhưng ta vẫn có thể “mô phỏng” chúng nhờ vào resolver.
Bạn có thể viết bất kì code gì trong resolver, vì thế mà bạn có thể dùng chúng để sửa đổi nội dung của database, vốn còn được gọi là mutation resolver.
Schema
Tất cả mọi thứ hay ho trên đều nhờ vào hệ thống GraphQL’s typed schema. Vì mục đích bài viết này chỉ là đơn giản giới thiệu nên tôi sẽ không có giải thích thêm cho rắc rối.
Tuy vậy, tôi khuyên bạn nên vào đọc GraphQL documentation nếu như có hứng thú.
Câu hỏi thường gặp
Mối quan hệ giữa GraphQL và graph database là như thế nào?
Thật ra là chẳng nhiều, như họ hàng rất xa ấy, GraphQL chả có dính dáng gì tới graph database như Neo4j. Phần “graph” đến từ ý tưởng theo dõi API graph bằng field và subfield trong khi “QL” ám chỉ cho “query language”
Rest vẫn còn tốt chán, sao lại phải chuyển qua GraphQL?
Nếu như bạn vẫn chưa bị phiền bởi sự hạn chế của Rest thì tốt thôi! Bởi việc dùng GraphQL thay vì REST chắc cũng sẽ không ảnh hưởng đến trải nghiệm người dùng từ app của bạn thế nên việc thay đổi cũng không phải mang tính sống còn hay gì. Tuy vậy, tôi vẫn khuyến khích bạn thử GraphQL trong một project nhỏ nếu có cơ hội.
Liệu tôi có thể dùng GraphQL mà không cần tới React/Relay/Các loại library?
Tất nhiên là được! Bởi GraphQL chỉ đơn giản là một kỹ thuật, bạn có dùng nó trên bất cứ library và platform nào bạn thích cùng với client hoặc tự tạo ra một GraphQL server.
GraphQL tạo ra bởi Facebook mà tôi thì chả tin vào Facebook
Lần nữa, GraphQL chỉ là một kĩ thuật, điều đó có nghĩa là bạn có thể dùng những ứng dụng của GraphQL mà không phải chạy bất kì một dòng code nào của Facebook.
Đồng thời với sự giúp đỡ của Facebook quả là một điểm cộng cho ecosystem của GraphQL, tại thời điểm này tôi tin rằng cộng đồng phát triển đã đủ lớn để GraphQL tiếp tục sống cho dù Facebook có ngưng xài nó.
Cả cái mô hình kinh doanh “để client yêu cầu data mà họ cần” nghe có vẻ không an toàn….
Tại bạn là người viết ra resolver, nó hoàn toàn phụ thuộc vào bạn để đưa ra những cách thức an ninh.
Nếu bạn cho phép client được phép truy cập một số các thông tin đặc biệt thì bạn sẽ muốn hạn chế số lượng nhằm tránh việc client yêu cầu quá nhiều.
Vậy tôi nên bắt đầu từ đâu đây?
Thông thường mà nói, bạn sẽ cần 2 thứ sau để có thể chạy một app tạo ra từ GraphQL:
- một GraphQL server với mục đích phục vụ cho API của bạn
- một GraphQL client để kết nối với endpoint của bạn
Điều đầu tiên bạn cần là một GraphQL server. Bản thân GraphQL chỉ là một kĩ thuật thế nên vẫn còn nhiều khoảng trống cho việc cải thiện.
GraphQL-JS (Node)
Vốn là nguồn tham khảo để cải thiện cho GraphQL. Bạn có dùng nó kèm với express-graphql để tạo ra API server cho mình.
GraphQL-Server (Node)
Nhóm Apollo có riêng hẳn một GraphQL server implementation, tuy là không được biết đến nhiều như bản chính nhưng vẫn phát triển cực kì nhanh.
Các Platform khác
GraphQL.org có hẳn một list về các implementation của GraphQL trên các platform khác nhau
Relay
Relay là bộ GraphQL toolkit của chính Facebook. Tôi vẫn chưa xài đến nó, nhưng theo những gì nghe được thì có vẻ Relay được tạo ra dựa trên những yêu cầu của Facebook thế nên nó có vẻ hơi đòi hỏi quá mức kĩ thuật so với đại đa số người dùng.
Apollo Client
Dù chỉ mới xuất hiện nhưng đã nhanh chóng soán ngôi bá chủ, Apollo client thường bao gồm 2 yếu tố sau:
- Apollo Client, dùng để chạy GraphQL query trên các trình duyệt web cũng như lưu trữ data của họ.
- Một kết nối cho front-end framework của bạn (React-Apollo, Angular-Apollo, etc.)
Cần nhớ rằng nếu để ở chế độ default, Apollo-client sẽ lưu dữ liệu của nó bằng Redux, một library khá tốt với hệ ecosystem đa dạng.
Dù rằng GraphQL vẫn còn khá mới, đã có kha khá các open-source apps tận dụng nó:
VulcanJS
Đầu tiên tôi cần nói trước rằng tôi hiện tại đang là lead maintainer cho VulcanJS. Tôi tạo ra VulcanJS nhằm để mọi người tận dụng sức mạnh của React/GraphQL stack mà khỏi mất công viết code quá nhiều. Cứ nghĩ đơn giản nó giống như là “đường ray cho modern web ecosystem”, giúp bạn tạo ra những CRUD app (Kiểu như vầy) chỉ trong vài tiếng đồng hồ.
Gatsby
Là một trang generator cho React static, giờ đã được cung cấp bởi GraphQL kể từ phiên bản version 1.0. Dù nghe có vẻ là sự kết hợp lạ lùng nhưng nó thật sự cực kì mạnh mẽ. trong quá trình building, Gatsby có thể thu thập data đến từ nhiều nguồn của GraphQL API sau đó sử dụng chúng để tạo ra một static client-only React app hoàn chỉnh.
GraphiQL
GraphiQL cực kì hữu dụng cho trong trình duyệt IDE cho query GraphQL endpoints
DataLoader
Bởi vì các GraphQL query kết nối với nhau như mạng lưới, một query cũng có khả năng kích hoạt hàng loạt các database call khiến cho performance bị giảm mạnh do lag spike. Để tránh trường hợp đó, bạn có thể sử dụng những library DataLoader, vốn được phát triển bởi chính Facebook.
Create GraphQL Server
Create GraphQL Server là một command line utility nhằm giúp triển khai nhanh một GraphQL server nhờ vào Node server và Mongo database.
GraphQL-up
Tương tự như Create GraphQL Server, GraphQL-up cho phép bạn tạo ra GraphQL back-end cực nhanh nhờ vào GraphCool.
Cuối cùng, hiện tại đã có một số công ty thuộc dạng chuyên cung cấp “GraphQL-backend” dịch vụ sẽ lo cho bạn phần server nhờ đó mà việc tham gia vào
GraphQL ecosystem cũng trở nên đáng để thử hơn.
Graphcool
Một backend platform khá linh hoạt với sự kết hợp giữa GraphQL và AWS Lambda.
Scaphold
Thêm một dịch vụ GraphQL backend với nhiều tính năng tương tự như Graphcool.
Đã có khá nhiều nguồn trên mạng cho bạn thỏa thích dùng
GraphQL.org
Trang web chính chủ của GraphQL với khá nhiều tài liệu hữu ích cho bạn để bắt đầu làm quen với GraphQL.
LearnGraphQL
LearnGraphQL là một khóa học tương tác được tạo bởi các thành viên tại Kadira.
LearnApollo
LearnApollo cũng tương tự như LearnGraphQL và là một khóa dạy học miễn phí được tạo ra bởi Graphcool.
The Apollo Blog
The Apollo blog có hàng ngàn tư liệu và bài viết kĩ lưỡng về Apollo cũng như GraphQL.
GraphQL Weekly
Một newsletter về GraphQL được sưu tập bởi Graphcool team.
Sau khi đã trang bị cho mình những kiến thức về GraphQL thì bạn sẽ dùng chúng như thế nào? Hãy thử một số combo sau:
Apollo + Graphcool + Next.js
Nếu bạn đã làm quen với Next.js và React, ví dụ sau sẽ cho phép bạn set up một GraphQL endpoint nhờ vào Graphcool rồi query nó nhờ vào Apollo.
VulcanJS
Vulcan tutorial sẽ hướng dẫn bạn cách tạo ra một GraphQL data layer đơn giản, trên cả server và client. Do Vulcan là một all-in-one platform, cách tốt nhất là bắt đầu từ số 0. Nếu bạn cần sự giúp đỡ thì đừng ngại gì mà hãy vào đây.
GraphQL & React Tutorial
Chroma blog bao gồm 6 phần hướng dẫn cách tạo ra một React/GraphQL app dựa trên cách tiếp cận phát triển theo từng thành phần.
GraphQL có vẻ sẽ khá phức tạp khi bạn mới nhìn vào bởi nó là một kĩ thuật dựa trên nhiều lĩnh vực khác nhau của công nghệ hiện đại. Tuy nhiên, nếu bạn kiên tri học hỏi thì tôi tin rằng bạn sẽ hiểu được nó một cách tường tận.
Vì thế cho dù bạn có dùng nó hay không thì cũng đều đáng bỏ thời gian ra để làm quen với GraphQL. Hiện nay, càng ngày càng có nhiều công ty và framework sử dụng nó, rất có thể GraphQL sẽ trở thành một phần không thể thiếu cho các web developer trong tương lai.
Nguồn: blog.topdev.vn via medium