LogoLogo
Navigation
Advanced Javascript
Advanced Javascript
  • 😆Attribute Starts With Selector [name^="value"] (ok)
  • 🥹 Tìm hiểu về Map và Set trong javascript (ok)
  • 🫢 The Array.from() method returns an array from any iterable object. (ok)
  • 😍localeCompare() method compares two strings return sort order -1, 1,0 (for before, after, or equal)
  • 😍JavaScript Array some() method returns true (and stops) if the function returns true() (ok)
  • Add key value pair to all objects in array (ok)
  • 🥸Làm một sider tuyệt đẹp "Timed-Cards-Opening"
  • 🥸Scroll animations! How to add a flowing path like the Lusion site with SVG and Javascript (ok)
  • Chia sẽ code plugin tạo thời gian chờ tải cho nút download
  • 😛jQuery 1.9 .live,.delegate,.on is not a function (ok)
  • 😁Importing CSS Breakpoints Into JavaScript (ok)
  • The matchMedia() method returns a MediaQueryList with the results from the query. (ok)
  • Collect nhiều sách pdf (ok)
  • 😁Check device Agent chrome, firefox ... (ok)
  • === START Three.js and TypeScript ===
  • Setup Development Environment (ok)
  • === END Three.js and TypeScript ===
  • === START THREE.JS ===
  • 🥳Fundamentals - three.js manual
    • Light trong Three.js
  • == Start Nguyên tắc cơ bản ===
  • Nguyên tắc cơ bản
  • Thiết kế đáp ứng
  • nguyên thủy
  • 😅Điều chỉnh camera (ok)
  • 😅Điều chỉnh scale
  • 🥲Xử lý màn hình HD-DPI
  • 😃So sánh Mesh với Object3D
  • 😅Trục AxesHelper
  • 😅Tạo GridHelper
  • 😆MeshBasic, MeshLambert, MeshPhong, MeshToon, MeshStandard, MeshPhysical, Shader, RawShader
  • == End Nguyên tắc cơ bản ===
  • 🥰Bài viết mẫu thự hành tọa độ, quay (ok)
  • Giới thiệu HTML5 Canvas
  • Bài 1: Làm quen với môi trường 3D của ThreeJS
  • Bài 2: Dịch chuyển đối tượng 3D - Controls
  • Bài 3: makeup
  • Bài 4: Models loader
  • 😁Những trang học three.js
  • Source Code Example
  • === END THREE.JS ===
  • === START WebGL ===
  • 😇Trang học WebGL && Shador
  • 😅Tìm hiểu về OpenGL ES 2.0
  • Tìm hiểu về WebGL phần 1: thư viện đồ họa web.
  • Tìm hiểu WebGL Phần 2: Đi sâu vào cách code WebGL appication
  • Tìm hiểu WebGL Phần 3: Đi sau vào cách code WebGL appication - các ví dụ
  • Tìm hiểu WebGL Phần 4: Các ví dụ.
  • === END WebGL ===
  • 😃Getting started with systemjs full (ok)
  • Đọc thêm bài này Mô-đun ECMAScript và khả năng tương thích trình duyệt (ok)
  • 😖Thư viện chặn truy cập vào Devtool (ok)
  • === START JAVASCRIPT Vanila ===
  • 😄Làm cách nào để ngăn sự kiện onclick của cha mẹ kích hoạt khi nhấp vào con parent, child ? (ok)
  • 😁Bootstrap 5 - multi item carousel (ok)
  • Three dots ( … ) in JavaScript
  • "... Three Dots" đã thay đổi javascript như thếnào ?
  • Array-like objects, Chuyển đối tượng arguments thành array (ok)
  • 😇Making a short alias for document.querySelectorAll (ok)
  • JavasScript Siblings (ok)
  • JavaScript Modules Full (ok)
  • JavaScript select Element (ok)
  • === END JAVASCRIPT Vanila ===
  • Sử dụng async, await, bất đồng bộ lấy dữ liệu Pagination, sử dụng Deferred 👌 phần 2 (ok)
  • how to use multiple ternary operator in javascript, ?:, ?? (ok)
  • 😅[DATETIMEPICKER] jQuery Plugin Date and Time Picke Full (ok)
  • === START tutorial HYPERAPP ==
  • [HYPERAPP] Hyperapp - JavaScript micro-framework chỉ 1kB (ok)
  • [HYPERAPP] hyperapp-tutorial-step-1 (ok)
  • [HYPERAPP] hyperapp-tutorial-step-2 (ok)
  • [HYPERAPP] hyperapp-tutorial-step-3 (ok)
  • [HYPERAPP] hyperapp-tutorial-step-4 (ok)
  • === END tutorial HYPERAPP ==
  • Free and Open Source Web Builder Framework
  • 😁How to recursively fetch data from paginated API then combine into one array (ok)
  • 😆Create a form with dom with nested tags, Wrapping a set of DOM elements using JavaScript (ok)
  • 😇Array find, Tìm phần tử đầu tiên thỏa mãn điều kiện (ok)
  • 😁Array find, Tìm phần tử cuối cùng thỏa mãn điều kiện (ok)
  • Cách tích hợp bộ lọc select chọn nhanh Tỉnh, Thành & Quận, Huyện, districts, provinces (ok)
  • object with methods, you can simply call a method from the object returned. (ok)
  • Portfolio, Filter, Gallery, Tabmenu (ok)
  • JavaScript chạy bất đồng bộ như thế nào?, Microtask ,Macrotask, queueMicrotask bài viết hay (ok)
  • 😋Learn prototypejs 😒😒😒
  • === START JavaScript chuyên sâu ===
  • [JavaScript chuyên sâu] Higher order function trong JavaScript - phần 1 (ok)
  • [JavaScript chuyên sâu] - Higher order function - phần 2: closure, currying, callback
  • [JavaScript chuyên sâu] - So sánh Constructor Function và Factory Function
  • [JavaScript chuyên sâu] - 5 vai trò của Function: function, object, property, callback, constructor
  • [JavaScript chuyên sâu] : Đồng bộ và bất đồng bộ của JavaScript - phần 1: Callback
  • [JavaScript chuyên sâu]: Từ hàm IIFE tới Module Pattern
    • 😍IIFE=>Immediately Invoked Function Expression=>khởi tạo function & chạy ngay, import, export như nào
  • Tìm hiểu về Higher-Order Functions trong JavaScript
  • === END JavaScript chuyên sâu ===
  • QR-Card (ok)
  • === START DATATABLE ===
  • [DATATABLE] bộ lọc sử dụng các thẻ bên trong td matter.vn (ok)
  • 😁[DATATABLE] JQuery Datatables Editor - Alternative to the official one (ok)
  • Example: Datatables Add Edit Delete with Ajax, PHP & MySQL (ok)
  • [DATATABLE] fixedColumns, DataTable, Left and right fixed columns (ok)
  • [DATATABLE] Sử dụng thư viện dataTables.bootstrap.min.js && dataTables.bootstrap.min.js (ok)
  • [DATATABLE] DataTables.net with DataTableQueryBuilder sample input filter (ok)
  • [DATATABLE] How to use Tabledit plugin with jQuery Datatable in PHP Ajax (ok)
  • [DATATABLE] DataTables Custom Filter Demo (ok)
  • [DATATABLE] Datatable multiple checkbox demo (ok)
  • [DATATABLE] HTML5 export buttons (ok)
  • [DATATABLE] CodePen Home DataTable 2 Card view (ok)
  • [DATATABLE] DataTables - Column Search (ok)
  • [DATATABLE] CodePen Home dataTables conditional row and cell styling (ok)
  • [DATATABLE] DataTables example of styling Excel export(ok)
  • === END DATATABLE ===
  • 😅Bất ngờ về sử dụng Window History full 1 (ok)
  • 😁Bất ngờ về sử dụng Window History full 2, window.history.scrollRestoration,history.replaceState(ok)
  • workingHoursBetweenTimes, tính giờ làm việc, giờ làm thêm (ok)
  • 😅addDataToArray, cộng mảng đối tượng với điều kiện key == (ok)
  • You can get the number of days in a specified month (ok)
  • Lấy giá trị khác nhau đầu tiên, cuối trong một mảng Object (ok)
  • swiperjs.com (ok)
    • Swiper Slider (ok)
  • Một số cách viết ngắn gọn code trong JS phần 1 (ok)
  • Một số cách viết ngắn gọn code trong JS phần 2 (ok)
  • literal javascript, php (ok)
  • Bài toán kinh điển sử dụng three dots lấy tất cả các key của object, key same, plus (ok)
  • convert object to array javascript (ok)
  • ==== Start Google Sheet ====
  • Kintone width Appscript (ok)
  • [GOOGLE-SHEETS] Buttons in Google Sheets
  • [GOOGLE-SHEETS] thực hiện chuyển dữ liệu sang bản khác (ok)
  • [GOOGLE-SHEETS] method getRange (ok)
  • [GOOGLE-SHEETS] method getRange (ok)
  • Bài 1: Khai Báo Biến và Đọc Ghi Ô – Dải Ô (Cell / Range)
  • Bài 2: Các Hàm Lấy Giá Trị và Đặt Giá Trị Dải Ô getRange – getValues – setValues
  • Bài 3: Copy và Di Chuyển Dải Ô Sang Sheet khác
  • Bài 4: Vòng Lặp For
  • Bài 5: Di chuyển dòng từ Sheet này sang Sheet khác
  • [Help] – Chuyển Cột Sang Hàng (bỏ ô trống) (ok)
  • Bài 6: Câu lệnh điều kiện IF (ok)
  • Bài 7: Giới thiệu các Trigger App Script – onEdit onOpen
  • [Help] – Form nhập liệu đơn giản
  • Bài 8: Hộp thoại Dialog / Popup
  • Bài 9: Ghi công thức Google Sheet vào ô
  • Bài 10: Đọc Ghi Mảng (Array) App Script
  • Bài 11: Tạo xác thực dữ liệu phụ thuộc
  • Lấy Email người dùng đang hoạt động trên Google Sheet – getActiveUser
  • Bài 12: Liên kết Google Form – Sheet – Apps Script
  • [Series Email] Bài 1: Gửi Email bằng Apps Script cơ bản
  • [Series Email] Bài 2: Gửi Email Đính Kèm File – Hình Ảnh
  • [Series Email] Bài 3: Gửi Email Cho Danh Sách Nhập Vào Từ Google Sheet
  • Addon Email All in One | Email AI1 | RA MẮT BẢN THỬ NGHIỆM
  • [Series Email] Bài 4: Gửi Email Bcc Cho Danh Sách Nhập Vào Từ Google Sheet
  • [Series Email] Bài 5: Tạo Hộp Thoại Xem Email Trước Khi Gửi
  • [Series Email] Bài 6: Gửi Email Theo Template Cho Sẵn
  • [Series Email] Bài 7: Gửi Email Xác Nhận Điền Form (Email Confirmation)
  • [Series Email] Bài 8: Hẹn Giờ Gửi Email
  • SpreadsheetApp
  • Giới hạn các Service trong Apps Script
  • [CF] Lọc dải ô bao gồm dải ô khác
  • Cách lưu trữ trong Google Apps Script – PropertiesService
  • [CF] Custom Function Google Sheets là gì và Cách ‘cài đặt’
  • [CF] Tìm Ô – Có Giá Trị – Cuối Cùng Trong Cột – Google Sheets
  • [CF] Đếm số lần xuất hiện kí tự trong dải ô Google Sheets
  • [CF] Lọc dải ô không bao gồm
  • ==== End Google Sheet ====
  • [REDUCE] JavaScript Array reduce()
  • Merge object and split array by size, Trộn object và tách array theo size (ok)
  • Đặt điều kiện mới load js (ok)
  • Calculate working days between two dates in Javascript excepts holidays (ok)
  • Remove everything after a certain character remove replace (ok)
  • CodePen Home Image zoom on hover - auto run - view full (ok)
  • ======== Start Slider Revolution =======
  • How to start (ok)
  • Revolution Lightbox tham khảo
  • Mẫu và thực viện để thực hành (ok)
  • Tài liệu Slider Revolution Jquery 2.0 (ok)
  • Tài liệu Slider Revolution Jquery 4.1.2 (ok)
  • ======== End Slider Revolution =======
  • jQuery click / toggle between two functions (ok)
  • [TEXT ANIMATION] làm hiệu ứng chữ dòng trên xuất hiện trước rồi mới đến dòng dưới (ok)
  • Phát hiện phần tử xuất hiện ở màn hình, Detect element appearing on screen, view (ok)
  • what does !function in Javascript mean? (ok)
  • [WEBPACK] Một cách phân biệt khi bundle ra es5 hay es6 một ví dụ sử dụng webpack (ok)
  • Javascript Self Invoking Functions (ok)
  • ====== Start Convert ES5 class to ES6 class ====
  • VS Code tips: Convert ES5 class to ES6 class code action (ok)
  • ====== End Convert ES5 class to ES6 class ====
  • Get Substring between two characters using javascript (ok)
  • add Html Table rows data into JSON array Object (ok)
  • lightGallery, lightgalleryjs, Lightbox (ok)
  • same height (ok)
  • Hình ảnh :(
  • ============ Start serialize =============
  • jQuery serialize() Method (ok)
  • serialize width php mysql (ok)
  • serialize, serializeObject, serializeArray (ok)
  • How to access jQuery serialized data? (ok)
  • ============ End serialize =============
  • Sử dụng addQueryVar để thêm vào đường dẫn ajax (ok)
  • Cách tích hợp captcha style2.track360.xyz (ok)
  • Simple JavaScript Captcha Example (Client Side Captcha)
  • 😍Đoạn mã sử dụng translate.google.com (ok)
  • ========== Start [MultiLang] ===========
  • [MultiLang] MultiLang.js (ok)
  • [MultiLang] Localizing JavaScript apps with jQuery.i18n (ok) (full)
  • [MultiLang] jQuery i18n những điều nên biết (ok)
  • [MultiLang] How to Create a Multilingual Application using JavaScript
  • [MultiLang] Build multiple language website using jQuery and JSON based methods (ok)
  • [MultiLang] Switch Different Languages On The Webpage - jQuery multilang (ok)
  • [MultiLang] jquery-multilang (ok)
  • ========== End [MultiLang] ===========
  • [MINICOLORS] jquery.minicolors (ok)
  • jQuery - addClass ACTIVE--> set timeout --> cycle (ok)(online.vinmec.com)
  • WP Mapbox GL JS Settings key (ok)
  • Xử lý ảnh thiếu thuộc tính title, alt trên style2.track360.xyz (ok)
  • Register your schema (ok)
  • ========= Start Learn Graphql Website =======
  • 1. Query and Mutation types
  • ========= End Learn Graphql Website =======
  • [GRAPHQL] Tạo Database với Mysql (ok)
  • KẾT NỐI VỚI MYSQL – NODEJS – 05
  • 😍Quick start graphql (ok)
  • Hướng dẫn bắt đầu GraphQL với Node.js (Phần 1)
  • Hướng dẫn bắt đầu GraphQL với Node.js (Phần 2)
  • Cách bắt đầu với ứng dụng GraphQL, React, Apollo Client và Apollo Server
  • [Fullstack] Xây dựng forum bằng GraphQL, React, Apollo và Prisma - Part 1 (Application Introduction
  • 😍[Fullstack] Xây dựng forum bằng GraphQL, React, Apollo và Prisma - Part 2 (Backend - Project Setup a
  • [Fullstack] Xây dựng forum bằng GraphQL, React, Apollo và Prisma - Part 3 (Backend - Simple Mutation
  • [Fullstack] Xây dựng forum bằng GraphQL, React, Apollo và Prisma - Part 4 (Backend - Connect to Data
  • 😍Prisma Crud Full
    • 🥰Sử dụng kết hợp prisma.io với wordpress như nào?
    • [ERROR] gặp lỗi TypeError: Do not know how to serialize a BigInt (ok)
    • 😍Migrate MongoDB to MySQL using Prism Key Differences (ok)
  • Setting Up Prisma with MySQL: A Step-by-Step Guid
  • Tìm hiểu GraphQL, Xây dựng 1 GraphQL server với prisma
  • 🥹Đã có bài viết về sqlite, sqlite3 đầy đủ (ok)
  • 😍Querying Sequelize Full link sequelize.org (ok)
  • 😁Sqlite Sequelize Example (ok)
  • 😍CRUD with React and GraphQL Mysql (ok)
  • 😍A GraphQL Sqlite, sequelize Full (ok)
  • GraphQL in practice - Part 1: Xây dựng GraphQL server với Apollo Server, ExpressJS và MongoDB
  • GraphQL in practice - Part 2: Tạo ứng dụng GraphQL với Apollo Client và React
  • GraphQL in practice - Part 2: Tạo ứng dụng GraphQL với Apollo Client và React
  • TÌm hiểu về GraphQL
  • Cùng tìm hiểu về GraphQL
  • Simple Guidance For You In GraphQL
  • [GRAPHQL] Get started with Apollo Server (ok)
  • [GRAPHQL] Schema basics (ok)
  • [GRAPHQL] Subscriptions (ok)
  • [GRAPHQL] Unions and interfaces (ok)
  • Tham khảo: https://www.howtographql.com
  • Tìm hiểu GraphQL: Các khái niệm cơ bản (ok)
  • GraphQL Và Ưu Điểm Nổi Bật So Với Rest API?
  • Xây dựng server GraphQL với NodeJS (ok)
  • Tìm hiểu GraphQL
  • Xây dựng GraphQL server với Node.js
  • Ví dụ Tạo Restfull API - CRUD đơn giản với NodeJS, GraphQL (ok)
  • Sequelize with Node, Express & Mysql and it’s setup (ok)
  • Sequelize in Nodejs Part I
  • Sequelize in Nodejs Part II
  • Videos NodeJS + MySQL Database
  • NodeJS – Lưu trữ dữ liệu trên MySQL với Sequelize
  • Exploring The Node.js With MySQL Example Using Sequelize & Express
  • Tạo model, migration, seeds với Sequelize
  • Sử dụng passport với sequelize và MySQL
  • Tạo model, migration, seeds với Sequelize
  • GraphQL là gì? Bắt đầu với GraphQL
  • Xây dựng API sử dụng Laravel và GraphQL
  • How To Connect To MySql Database Using Sequlize In Express (Node) Application
  • Node.js MySQL Tutorial
  • Node.js Rest APIs example with Express, Sequelize & MySQL
  • Getting Started with Node, Express and Mysql Using Sequelize
  • [GRAPHQL] GraphQL – Công nghệ mới cho web developer
  • GraphQL là gì? Tìm hiểu về GraphQL (ok)
  • [GRAPHQL] Cùng tìm hiểu về GraphQL
  • Điều gì ẩn chứa bên trong $.event???
  • ===== Start Put JavaScript Design Patterns Into Practice (Videos) ========
  • 2.1. The Factory Pattern (ok)
  • 3.1. The Publisher-Subscriber Pattern (ok)
  • 3.2. The Strategy Pattern (ok)
  • Rời phần thử khỏi mảng sử dụng filter (ok)
  • 3.3. The Observer Pattern (ok)
  • 3.4. The Chain of Responsibility Pattern (ok)
  • 3.5. The Mediator Pattern (ok)
  • 3.6. The Iterator Pattern (ok)
  • ===== End Put JavaScript Design Patterns Into Practice (Videos) ========
  • ========== Start RequireJS Tutorial =======
    • Sử dụng RequireJS và AMD để module hóa code JavaScript (ok)
  • 😍Trình duyệt không có require, nhưng Node.js thì có. Với Browserify để trình duyệt cũng có (ok)
  • Sử dụng Bower để quản lý các thư viện code trong Laravel (ok)
  • RequireJS - Environment Setup (ok)
  • RequireJS - Configuration (ok)
  • RequireJS - AMD Modules (ok)
  • RequireJS - Defining Function (cách sử dụng require rất lạ) (ok)
  • RequireJS - Optimizer (ok)
  • ========== End RequireJS Tutorial =======
  • ========== Start jQuery Ui ======
  • Jquery Datepicker select multiple date ranges in one calender, button Reset (ok)
  • Tạo chức năng tự động hoàn tất nhập liệu với thư viện jQuery UI Autocomplete (Phần 1) (ok)
  • Draggable Widget, Droppable Widget (ok)
  • jQuery drag and drop (kéo thả bằng jQuery)
  • jQuery drag full (ok)
  • jQuery drop full (ok)
  • jQuery Resizable full (ok)
  • Tablesorter full (ok)
  • Live search through table rows (ok)
  • Loại bỏ một số cột không tìm kiếm trong Tablesorter (ok)
  • jQuery Sortable full, tablesorter (ok)
  • jQuery Selectable full (ok)
  • jQuery UI Sortable Tutorial - Save Positions With Ajax & PHP & MySQL (ok)
  • jQuery Drag and Drop TODO List with PHP MySQL (ok)
  • ========== End jQuery Ui ======
  • [TUTORIAL] TRÍCH XUẤT THÔNG TIN TỪ WEBSITE VỚI HTML AGLITITY PACK
  • ======== Start handlebars js =======
  • Sử dụng handlebars js
  • Handlebars nhỏ nhưng có võ
  • ======== End handlebars js =======
  • ==== Start JavaScript Tutorial ====
  • JavaScript Introduction
  • What is JavaScript
  • JavaScript Essentials
  • JavaScript Variables
  • JavaScript Operators
  • JavaScript Conditionals
  • JavaScript Loops
  • JavaScript Built-in Types
  • JavaScript Objects
  • JS Advanced Objects
  • JavaScript Arrays
  • JavaScript Functions
  • JavaScript Function Objects
  • JavaScript JSON
  • JavaScript Regular Expressions
  • Bôi màu cho một ký tự đặc biệt và chuỗi @EsportsArcadia Regular Expression (ok)
  • JavaScript Reference
  • ==== End JavaScript Tutorial ====
  • 🧐===== Start JavaScript Design Patterns ==
  • JavaScript Design Patterns
  • JavaScript Design Patterns – Explained with Examples
  • Js design pattern doFactory master (ok)
  • Chapter 5: jQuery Patterns
  • JavaScript Design Patterns (ok)
  • Abstract Factory (ok)
  • Builder (ok)
  • Factory Method (ok)
  • Prototype (ok)
  • Singleton (ok)
  • Adapter ( ok)
  • Bridge (ok)
  • Composite (ok)
  • Decorator (ok)
  • Facade (ok)
  • Flyweight (ok)
  • Proxy (ok)
  • Chain of Responsibility (ok)
  • Command (ok)
  • Interpreter (ok)
  • Iterator (ok)
  • Mediator (ok)
  • Memento (ok)
  • Observer (ok)
  • State (ok)
  • Strategy (ok)
  • Template Method (ok)
  • Visitor (ok)
  • ===== End JavaScript Design Patterns ==
  • ======== Start Backbone.js Tutorial Videos ======
  • Backbone.js Tutorial - 1 - Installation.mp4 (ok)
  • Backbone.js Tutorial - 2 - Introduction to Models (ok)
  • Backbone.js Tutorial - 3 - Model Attributes (ok)
  • Backbone.js Tutorial - 4 - Model Change Events ( ok)
  • Backbone.js Tutorial - 6 - Introduction to Views (ok)
  • Backbone.js Tutorial - 7 - (Views) Differerence between el and $el (ok)
  • Backbone.js Tutorial - 8 - (Views) Creating New HTML Elements (ok)
  • Backbone.js Tutorial - 9 - (Views) Using the Render Function (ok)
  • Backbone.js Tutorial - 10 - (Views) Events (ok)
  • Backbone.js Tutorial - 11 - Introduction to Collections (ok)
  • Backbone.js Tutorial - 12 - (Collections) Adding and Removing Elements (ok)
  • Backbone.js Tutorial - 13 - (Collections) Modifying Elements
  • Backbone.js Tutorial - 14 - (Collections) Events (ok)
  • ======== End Backbone.js Tutorial Videos ======
  • ====== Start Learn backbone.js tutorial from scratch for beginners =====
  • Backbone :)
  • 1. Learn backbone.js tutorial from scratch(Part 2) Features and Working Principle of backbone.js
  • 2. Learn backbone.js tutorial from scratch for beginners(Part 4) About el and $el in Backbone.js
  • 3. Learn backbone.js tutorial from scratch for beginners(Part 5) Underscore Templates in Backbone.js
  • 4. Learn backbone.js tutorial from scratch for beginners (Part 7) Delegate Events in backbone.js
  • 5. Learn backbone.js tutorial from scratch for beginners(Part 8) Introduction of models in backbone.
  • 6. Learn backbone.js tutorial from scratch for beginners(Part 9) Pass Model data to backbone.js View
  • 7. Learn backbone.js tutorial from scratch for beginners(Part 10) Model data to underscore.js templ
  • 8. Learn backbone.js tutorial from scratch for beginners(Part 11) Head back to underscore.js symbol
  • 9. Learn backbone.js tutorial from scratch for beginners(Part 12) Model Events in backbone.js
  • 10. Learn backbone.js tutorial from scratch for beginners(Part 13) Model Validation in backbone.js
  • 11. Learn backbone.js tutorial from scratch for beginners(Part 14) Model Change Events in backbone.j
  • 12. Learn backbone.js tutorial from scratch for beginners(Part 15) More Model Events and listenTo ev
  • 13. Learn backbone.js tutorial from scratch for beginners(Part 16) Model Inheritance in backbone.js
  • 14. Learn backbone.js tutorial from scratch for beginners(Part 17) Collection in backbone js
  • 15. Learn backbone.js tutorial from scratch for beginners(Part 18) Collection Events in backbone.js
  • 16. Learn backbone.js tutorial from scratch for beginners(Part 19) Collection to underscore.js templ
  • 17. Learn backbone.js tutorial from scratch for beginners(Part 20) Underscore js Methods in backbone
  • 18. Learn backbone.js tutorial from scratch for beginners(Part 21) Routing in backbone.js
  • 19. Learn backbone.js tutorial from scratch for beginners(Part 22) Parameterized Routing in backbone
  • 20. Learn backbone.js tutorial from scratch for beginners(Part 23) Handlebars templates in backb
  • ====== End Learn backbone.js tutorial from scratch for beginners =====
  • Giới thiệu Backbone.js (ok)
  • Backbone.localStorage thay thế Backbone.sync lưu vào window.localStorage thay vì vào máy chủ (ok)
  • Một ví dụ full LocalStorage với BackBoneJS (ok)
  • ========== Start Backbonejs Php Mysql =============
  • Full code backbonejs php mysql (ok)
  • Giao diện html để thực hành từ đầu (ok)
  • Xây dựng giao diện (ok)
  • Thực hiện chức năng crud add (ok)
  • Phân tích để tạo giao diên http://localhost/gulp/#crud/new 1.0
  • Phân tích để tạo giao diên http://localhost/gulp/#crud/new 1.1
  • Phân tích để tạo giao diên http://localhost/create/#crud/index 2.0
  • Chức năng thêm dữ liệu http://localhost/create/#crud/new (ok)
  • Lấy dữ liệu ra trang http://localhost/create/#crud/index (ok)
  • Chức năng cập nhật dữ liệu http://localhost/create/#crud/1/edit (ok)
  • ========== End Backbonejs Php Mysql =============
  • JQuery-Template (ok)
  • Learning JavaScript Design Patterns P.1 (ok)
  • Learning JavaScript Design Patterns P.2 (ok)
  • Learning JavaScript Design Patterns P.3 (ok)
  • Singleton design pattern PHP (ok)
  • Singleton Pattern javascript (ok)
  • Factory Pattern (ok)
  • Decorator Pattern (ok)
  • Creational Pattern (ok)
  • Constructor Pattern (ok)
  • Singleton Pattern (ok)
  • Module Pattern (ok)
  • Factory pattern (ok)
  • Built-in Object Factory (ok)
  • Iterator (ok)
  • Bridge Pattern (ok)
  • Composite Pattern (ok)
  • Một số Design Patterns có thể sử dụng trong Javascript – Phần 1 (ok)
  • Chém gió về JavaScript Design Pattern - Part 1(ok)
  • Chém Gió Về JavaScript Design Pattern Phần 2
  • Chém gió về JavaScript Design Pattern - Part 3
  • 4 Design Patterns trong Javascript mà bạn nên biết
  • Design Pattern trong JavaScript (ok)
  • Lebab chuyển mã ES5 của bạn thành ES6 / ES7. Nó hoàn toàn ngược lại với những gì Babel làm (ok)
  • Turn your ES5 code into readable ES6 (ok)
  • Thuộc tính :selected quá tuyệt cho sự lựa chọn (ok)
  • jQuery I want to add an active class to the linked ID of an anchor tag style2.track360.xyz (ok)
  • Keep URL unaffected when anchor link is clicked (ok)
  • [UI SLIDER] Ui slider with text box input (ok)
  • [SELECT2] version Select2 3.5.3 nhìn trực quan hơn (ok)
  • [SELECT2] keypress select2, enter key press keycode yp.vn (ok)
  • [SELECT2] Select2 Bootstrap Theme (ok)
  • [SELECT2] tags (ok)
  • [SELECT2] tokenSeparators (ok)
  • [SELECT2] click change value (ok)
  • [SELECT2] jQuery $.ajax options (ok)
  • [SELECT2] Full Options (ok)
  • [SELECT2] value placeholder (ok)
  • [SELECT2] Can thiệp vào templateResult (ok)
  • [SELECT2] làm lá cờ gắn trước text kiểu kool ngầu (ok)
  • [SELECT2] cam thiệp vào templateSelection (ok)
  • [SELECT2] thêm thẻ bọc vào lựa chọn ví dụ thẻ <strong/> (ok)
  • [SELECT2] opening when a result is selected (ok)
  • [SELECT2] Full Adapters hay (ok)
  • [SELECT2] Kiểu dữ liệu trả về cho giao diện dùng html & json (ok)
  • [SELECT2] sử dụng ngôn ngữ, i18n, language (ok)
  • [SELECT2] dropdownParent (ok)
  • [SELECT2] Hiểu submit trong javascript và nâng cấp sử dụng select 2, autocomplate (ok)
  • [SELECT2] Common problems Select2 does not function properly when I use it inside a Bootstrap modal
  • [SELECT2] Full Events (ok)
  • [SELECT2] lấy dữ liệu của wp, wordpress để thực hành (ok)
  • [JSONPLACEHOLDER SELECT2] Full Sử dụng website jsonplaceholder.typicode.com để thực hành (ok)
  • Sử dụng fetch trên console.log để get api test (ok)
  • jQuery.naturalWidth / jQuery.naturalHeight images natural Width Height Native Width (ok)
  • [SUBMIT ] form submit jquery (ok)
  • Tạo file package.json bằng lệnh (ok)
  • [TYPESCRIPT] tạo file tsconfig.json bằng lệnh (ok)
  • [TYPESCRIPT] cài đặt package chạy trực tiếp ts, tsx, ts-node (ok)
  • Object for Three Dots, Array for Three Dots (ok)
  • Cách giải thích Private Constructors & Singletons quá tuyệt (ok)
  • [TYPESCRIPT] Một số scripts hay được sử dụng trong typescripts (ok)
  • [TYPESCRIPT] A practical guide to TypeScript decorators exmaple (ok)
  • Object.getOwnPropertyDescriptor() (ok)
  • JavaScript — Property Descriptor && PropertyDescriptor (ok)
  • [TYPESCRIPT] Employing “Namespaces” in TypeScript to encapsulate your data
  • 😅[TYPESCRIPT] Một ví dụ sử dụng TypeScript Namespaces, xuất file use on browser (ok)
  • [NODEJS] object hóa một file trong javascript Nodejs - require, exports and module.exports
  • [TYPECRIPT] Omit type when extending an interface Cách loại trừ các thuộc tính khỏi giao diện (ok)
  • How TO - List Grid View (ok)
  • Javascript module, import, export, dễ ẹc, nhưng có thể bạn vẫn chưa biết
  • [BABEL] Giải thích gói babel (ok)
  • Cấu hình Webpack và Babel 7 cho React (ok)
  • ----------------- Start Kế thừa Prototype ngang và dọc -------------------
  • Kế thừa Prototype ngang và dọc
  • class, super, constructor (ok)
  • Kế thừa ngang giữa function (ok)
  • Ví dụ về kế thừa prototype ngang theo function constructor. Liên quan đến hàm call(), sẽ có bài chi
  • Kế thừa ngang giữa 2 object
  • Muốn tạo một class, object có tên k hác khi console.log?? (ok)
  • Ví dụ về Function constructor và object instance (ok)
  • Tất cả đều từ Function
  • ----------------- End Kế thừa Prototype ngang và dọc -----------
  • Easy Responsive Tabs to Accordion (ok)Demos
  • [ERROR] unable to read package/javascript (ok)
  • ------------Start Json-----------------
  • Cách để truyền dữ liệu dạng boolean trong Postman (ok)
  • ------------ End Json-----------------
  • ---------- start JSONP ---------------------
  • Cross-Domain Ajax Requests
  • 1. JSONP (JSON with padding)
  • 2. CORSCross-origin resource sharing (CORS) là một cơ chế đặc biệt cho phép resource đặt tại một do
  • 3. Proxy
  • JSONP là gì và tại sao nó được tạo ra? (ok)
  • 4. Javascript – Tạo script động và kĩ thuật JSONP (ok)
  • ----------- End JSONP --------------
  • Destructuring Assignment in ES6
  • Cơ chế bất đồng bộ trong javascript (ok)
  • jQuery.inArray()
  • website check call stack (ok)
  • Bài 6: Template Literals trong ES6 (ok)
  • ES6 Arrow Functions (ok)
  • Lập trình TypeScript (ok)
  • Uncaught ReferenceError: exports is not defined in filed generated by Typescript (ok)
  • Cách hoạt động của các module loader? (ok) một ví dụ kinh điển :)
  • RequireJS Cho Người Mới Bắt Đầu (ok) quá tuyệt
  • Tiny loaders tương tự REQUIREJS (Ok)
  • Javascript Module Loader – From the basic (ok)
  • ES6 Modules and CommonJS (Oke) Một ví dụ quý hơn vàng :(((
  • CommonJS là một module pattern hỗ trợ cho tất cả các phiên bản Node.js. Với CommonJS, JavaScript obj
  • ------------------------Start webpack ----------------------
  • [WEBPACK] Làm một ví dụ compile scss, sass bằng WEBPACK full (ok)
  • Webpack từ A đến Á: Webpack watch mode (ok)
  • Webpack từ A đến Á: Webpack dev server (ok)
  • Webpack từ A đến Á: Webpack output hash digest (ok)
  • Webpack từ A đến Á: Webpack multiple entry points (ok)
  • Webpack từ A đến Á: Webpack multiple file types per entry (ok)
  • Webpack từ A đến Á: Webpack import export module (ok)
  • Webpack từ A đến Á: Webpack source map (ok)
  • Webpack từ A đến Á: Webpack import jQuery (ok)
  • Webpack từ A đến Á: Webpack import jQuery - Bootstrap (ok)
  • Webpack từ A đến Á: Webpack import jQuery - Materialize
  • Webpack từ A đến Á: Code Splitting (ok)
  • Webpack từ A đến Á: Code Splitting (ok)
  • Webpack từ A đến Á: Webpack resolve alias - extensions
  • Config alias chuẩn trong webpack (ok)
  • Webpack từ A đến Á: Webpack Babel Loader (ok)
  • Webpack từ A đến Á: Webpack Eslint Loader (ok)
  • Webpack từ A đến Á: Webpack Url Loader (ok)
  • Webpack từ A đến Á: Webpack File Loader (ok)
  • Webpack từ A đến Á: Webpack Style Loader (ok)
  • Webpack từ A đến Á: Webpack Sass Loader (ok)
  • Webpack từ A đến Á: Html Webpack Plugin (ok)
  • Option chunks Html Webpack Plugin (ok)
  • Webpack từ A đến Á: Clean Webpack Plugin (ok)
  • What is the difference between @babel/core and babel-core? (ok)
  • [WEBPACK] 2. Webpack : Khởi Tạo Project (nghiepuit)
  • [WEBPACK] 3. Webpack : Apply Babel Cho Project (nghiepuit)
  • [WEBPACK] 4. Webpack : CSS Loader (nghiepuit)
  • plugin @babel/plugin-proposal-class-properties
  • [WEBPACK] 5. Webpack : Tạo Project ReactJS (
  • [WEBPACK] 7. Webpack : File Loader - Tích Hợp Bootstrap
  • [WEBPACK] 8. Webpack : Tích Hợp Jquery, React, Redux Devtools (nghiepuit)
  • [WEBPACK] 9. Webpack : Vendor Caching
  • [WEBPACK] 10. Webpack : CommonsChunkPlugin
  • [WEBPACK] 10. Webpack : CommonsChunkPlugin (ok)
  • [WEBPACK] Webpack series (ep3) - code splitting - chia code trong webpack (ok)
  • Compile SASS with Webpack into a CSS file (ok)
  • [WEBPACK] 11. Webpack : Optimize Khi Bundle template (ok)
  • [WEBPACK] 12. Webpack : Clean Project (ok)
  • [WEBPACK] 12+. Webpack : webpack-dev-server
  • [WEBPACK] Plugin HtmlWebpackPlugin (ok)
  • HashRouter vs BrowserRouter
  • [WEBPACK] Webpack giúp kết nối các module lại với nhau ( (ok)
  • [WEBPACK] Chú ý: @babel/preset-env dùng cho những gói cũ thay vì khai báo mới babel-preset-env (ok)
  • [WEBPACK]
  • [WEBPACK] webpack-dev-server (ok)
  • [WEBPACK] liên kết với trang Webpack (ok)
  • [WEBPACK] Webpack output hash digest (ok)
  • [WEBPACK] Webpack multiple file types per entry
  • [WEBPACK] Webpack import export module (ok)
  • [WEBPACK] Webpack source map (ok)
  • Simple use jQuery with TypeScript (ok)
  • [WEBPACK] Webpack import jQuery (ok)
  • [WEBPACK] Webpack import jQuery - Bootstrap (ok)
  • [WEBPACK] Webpack import jQuery - Materialize
  • [WEBPACK] Webpack từ A đến Á: Code Splitting
  • [WEBPACK] Webpack từ A đến Á: Webpack resolve alias - extensions
  • [WEBPACK] Config alias chuẩn trong webpack
  • [WEBPACK] Webpack từ A đến Á: Webpack Babel Loader
  • [WEBPACK] Webpack từ A đến Á: Webpack Eslint Loader
  • [WEBPACK] Webpack từ A đến Á: Webpack Url Loader (ok)
  • [WEBPACK] Webpack từ A đến Á: Webpack File Loader
  • [WEBPACK] Webpack từ A đến Á: Webpack Style Loader (ok)
  • [WEBPACK] Webpack từ A đến Á: Webpack Css Loader
  • [WEBPACK] Webpack từ A đến Á: Webpack Sass Loader
  • [WEBPACK] [SPITEST] Teach you how to use webpack to generate css sprites
  • Page learn webpack good
  • Remove unused CSS styles from Bootstrap using PurgeCSS (ok)
  • [WEBPACK] Webpack cho người mới bắt đầu (ok)
  • [WEBPACK] cấu hình output (ok)
  • [WEBPACK] Dùng webpack để sử dụng từ khóa import, export (ok)
  • [WEBPACK] Từ cơ bản đến nâng cao
  • [WEBPACK] Tăng Tốc Độ và Tối Ưu Hoá Website Bằng CSS Sprites (ok)
  • ------------------------ End webpack ----------------------
  • How to convert unordered list into nicely styled <select> dropdown using jquery? (ok)
  • 😆Lazy loading images using event handlers 1
  • 😄Layload ajax && background 2
  • jQuery Lazy 3
  • jQuery lazyload 4
  • Config lazySizesConfig lazysizes.min.js lazysizes(ok)
  • Lazy loading images using event handlers (ok)
  • GIỚI THIỆU THƯ VIỆN LAZYSIZES.JS ĐỂ LAZY LOAD ẢNH (PHẦN 1)
  • GIỚI THIỆU THƯ VIỆN LAZYSIZES.JS ĐỂ LAZY LOAD ẢNH (PHẦN 2)
  • GIỚI THIỆU THƯ VIỆN LAZYSIZES.JS ĐỂ LAZY LOAD ẢNH (PHẦN 3)
  • Native lazy-loading for the web (ok)
  • Tầm quan trọng của thuộc tính sizes, srcset trong thẻ img (ok)
  • Thực hành lazysizes.min.js
  • Check image img exits vieclam123.vn (ok)
  • Nestable - Drag & drop hierarchical list with mouse and touch compatibility (ok)
  • Cấu hình tawk chat web500.vn ( ok)
  • Cùng tìm hiểu plugin Jquery Validation
  • Tìm hiểu về Jquery Validation (Phần 1) (ok)
  • Tìm hiểu về Jquery Validation (Phần 2) (ok)
  • Tìm hiểu về hộp thoại Sweet alert 2
  • Multi-table,Multi table (ok)
  • SweetAlert2 getHtmlContainer (ok)
  • AJAX request preConfirm (ok)
  • sử dụng php kết hợp Sweetalert2 (ok)
  • Một ví dụ tuyệt vời Ajax SweetAlert for Live Data Deleting Rows in with PHP~MySQL~Ajax (ok)
  • SweetAlert makes popup messages easy and pretty (page learn) (kiể cũ)
  • sweetalert bản chuẩn (ok)
  • AJAX requests (ok)
  • sweetalert2 bản chuẩn (ok) cái này dùng hay hơn sweetalert (ok)
  • Toast (ok)
  • Email (ok)
  • jQuery trigger() Method
  • jQuery one() Method (ok)
Powered by GitBook

Navigation

  • Lionel

@Copyright 2023

On this page
  • Schema definition
  • Setting a subscription endpoint
  • Resolving a subscription
  • Basic runnable example
  • Operation context
  • onConnect and onDisconnect
  • Using with middleware integrations
  • Production PubSub libraries

[GRAPHQL] Subscriptions (ok)

https://www.apollographql.com/docs/apollo-server/data/subscriptions/

Previous[GRAPHQL] Schema basics (ok)Next[GRAPHQL] Unions and interfaces (ok)

Last updated 4 years ago

Đăng ký là hoạt động đọc GraphQL lâu dài có thể cập nhật kết quả của chúng bất cứ khi nào một sự kiện phía máy chủ cụ thể xảy ra. Thông thường nhất, các kết quả cập nhật được đẩy từ máy chủ đến các khách hàng đăng ký. Ví dụ: máy chủ của ứng dụng trò chuyện có thể sử dụng đăng ký để đẩy các tin nhắn mới nhận được đến tất cả các khách hàng trong một phòng trò chuyện cụ thể.

Vì các bản cập nhật đăng ký thường được đẩy bởi máy chủ (thay vì được khách hàng thăm dò), chúng thường sử dụng giao thức WebSocket thay vì HTTP. Để hỗ trợ điều này, Apollo Server cho phép bạn đặt điểm cuối dành riêng cho đăng ký tách biệt với điểm cuối mặc định cho các truy vấn và đột biến.

Bạn có thể sử dụng đăng ký với thư viện apollo-server cốt lõi hoặc với bất kỳ tích hợp phần mềm trung gian nào được hỗ trợ của Apollo Server.

Quan trọng: So với truy vấn và đột biến, đăng ký phức tạp hơn đáng kể để triển khai. Trước khi bạn bắt đầu, hãy xác nhận rằng trường hợp sử dụng của bạn yêu cầu đăng ký.

Loại Đăng ký trong lược đồ của bạn xác định các trường cấp cao nhất mà khách hàng có thể đăng ký:

type Subscription {
  postCreated: Post
}

Trường postCreate sẽ cập nhật giá trị của nó bất cứ khi nào một Bài đăng mới được tạo trên chương trình phụ trợ, do đó đẩy Bài đăng đến các khách hàng đăng ký.

Clients can subscribe to the postCreated field with a GraphQL string like this:

subscription PostFeed {
  postCreated {
    author
    comment
  }
}

Mỗi thao tác đăng ký chỉ có thể đăng ký một trường của loại Đăng ký.

Bởi vì đăng ký sử dụng WebSocket thay vì HTTP, Apollo Server sử dụng điểm cuối GraphQL thứ hai dành riêng cho đăng ký. Điểm cuối này sử dụng giao thức ws thay vì http.

Theo mặc định, đường dẫn của điểm cuối đăng ký khớp với đường dẫn của điểm cuối GraphQL chính của bạn (/ graphql nếu chưa được đặt). Bạn có thể chỉ định một đường dẫn khác cho điểm cuối đăng ký của mình như sau:

const server = new ApolloServer({
  subscriptions: {
    path: '/subscriptions'
  },
  // ...other options...
}));

Trình phân giải cho các trường Đăng ký khác với trình phân giải cho các trường thuộc loại khác. Cụ thể, trình phân giải trường Đăng ký là các đối tượng xác định chức năng đăng ký:

index.js

const resolvers = {
  Subscription: {
    postCreated: {
      // More on pubsub below
      subscribe: () => pubsub.asyncIterator(['POST_CREATED']),
    },
  },
  // ...other resolvers...
};

The subscribe function must return an object of type AsyncIterator, a standard interface for iterating over asynchronous results. In the example above, an AsyncIterator is generated by pubsub.asyncIterator (more on this below).

Hàm đăng ký phải trả về một đối tượng kiểu AsyncIterator, một giao diện tiêu chuẩn để lặp qua các kết quả không đồng bộ. Trong ví dụ trên, một AsyncIterator được tạo bởi pubsub.asyncIterator (thêm về điều này bên dưới).

Lớp PubSub không được khuyến nghị cho môi trường sản xuất, vì nó là hệ thống sự kiện trong bộ nhớ chỉ hỗ trợ một phiên bản máy chủ duy nhất. Sau khi bạn nhận được các đăng ký đang hoạt động trong quá trình phát triển, chúng tôi thực sự khuyên bạn nên chuyển nó sang một lớp con khác của lớp PubSubEngine trừu tượng. Các lớp con được đề xuất được liệt kê trong thư viện Production PubSub.

Apollo Server sử dụng mô hình đăng ký xuất bản (pub / sub) để theo dõi các sự kiện cập nhật các đăng ký đang hoạt động. Thư viện graphql-subscribe (bao gồm trong mọi gói apollo-server) cung cấp lớp PubSub như một bus sự kiện trong bộ nhớ cơ bản để giúp bạn bắt đầu:

const { PubSub } = require('apollo-server');
const pubsub = new PubSub();

Một phiên bản PubSub cho phép mã máy chủ của bạn vừa xuất bản các sự kiện lên một nhãn cụ thể vừa lắng nghe các sự kiện được liên kết với một nhãn cụ thể.

Bạn xuất bản một sự kiện bằng phương pháp xuất bản của một phiên bản PubSub:

pubsub.publish('POST_CREATED', {
  postCreated: {
    author: 'Ali Baba',
    comment: 'Open sesame'
  }
});
  • The first parameter is the name of the event label you're publishing to, as a string.

    • You don't need to register a label name before publishing to it.

  • The second parameter is the payload associated with the event.

    • The payload should include whatever data is necessary for your resolvers to populate the associated Subscription field and its subfields

  • Tham số đầu tiên là tên của nhãn sự kiện mà bạn đang xuất bản, dưới dạng một chuỗi.

    • Bạn không cần phải đăng ký tên nhãn trước khi xuất bản lên nó.

  • Tham số thứ hai là trọng tải được liên kết với sự kiện.

    • Tải trọng phải bao gồm bất kỳ dữ liệu nào cần thiết để trình phân giải của bạn điền vào trường Đăng ký được liên kết và các trường con của nó.

Khi làm việc với đăng ký GraphQL, bạn xuất bản một sự kiện bất cứ khi nào giá trị trả về của đăng ký được cập nhật. Một nguyên nhân phổ biến của bản cập nhật như vậy là một đột biến, nhưng bất kỳ logic back-end nào cũng có thể dẫn đến các thay đổi cần được xuất bản.

As an example, let's say our GraphQL API supports a createPost mutation:

type Mutation {
  createPost(author: String, comment: String): Post
}

A basic resolver for createPost might look like this:

const resolvers = {
  Mutation: {
    createPost(parent, args, context) {
      // Datastore logic lives in postController
      return postController.createPost(args);
    },
  },
  // ...other resolvers...
};

Trước khi chúng tôi duy trì thông tin chi tiết của bài đăng mới trong kho dữ liệu của mình, chúng tôi có thể xuất bản một sự kiện cũng bao gồm các chi tiết đó:

const resolvers = {
  Mutation: {
    createPost(parent, args, context) {
      pubsub.publish('POST_CREATED', { postCreated: args });
      return postController.createPost(args);
    },
  },
  // ...other resolvers...
};

Next, we can listen for this event in our Subscription field's resolver.

An AsyncIterator object listens for events that are associated with a particular label (or set of labels) and adds them to a queue for processing. You create an AsyncIterator by calling the asyncIterator method of PubSub:

Đối tượng AsyncIterator lắng nghe các sự kiện được liên kết với một nhãn cụ thể (hoặc tập hợp các nhãn) và thêm chúng vào một hàng đợi để xử lý. Bạn tạo một AsyncIterator bằng cách gọi phương thức asyncIterator của PubSub:

pubsub.asyncIterator(['POST_CREATED']);

You pass this method an array containing the names of all event labels that the AsyncIterator should listen for.

Bạn truyền cho phương thức này một mảng chứa tên của tất cả các nhãn sự kiện mà AsyncIterator sẽ lắng nghe.

Every Subscription field resolver's subscribe function must return an AsyncIterator object. This brings us back to the code sample at the top of Resolving a subscription:

Mọi chức năng đăng ký của trình phân giải trường Đăng ký phải trả về một đối tượng AsyncIterator. Điều này đưa chúng ta trở lại mẫu mã ở đầu Giải quyết đăng ký:

index.js

const resolvers = {
  Subscription: {
    postCreated: {
      subscribe: () => pubsub.asyncIterator(['POST_CREATED']),
    },
  },
  // ...other resolvers...
};

With this subscribe function set, Apollo Server uses the payloads of POST_CREATED events to push updated values for the postCreated field.

Với bộ chức năng đăng ký này, Apollo Server sử dụng trọng tải của các sự kiện POST_CREATED để đẩy các giá trị cập nhật cho trường postCreate.

Đôi khi, khách hàng sẽ chỉ nhận được dữ liệu đăng ký cập nhật nếu dữ liệu đó đáp ứng các tiêu chí nhất định. Để hỗ trợ điều này, bạn có thể gọi hàm trợ giúp withFilter trong trình phân giải của trường Đăng ký của bạn.

Example

Let's say our server provides a commentAdded subscription, which should notify clients whenever a comment is added to a specified code repository. A client can execute a subscription that looks like this:

Giả sử máy chủ của chúng tôi cung cấp đăng ký commentAdded, đăng ký này sẽ thông báo cho khách hàng bất cứ khi nào nhận xét được thêm vào kho mã được chỉ định. Khách hàng có thể thực hiện một đăng ký giống như sau:

subscription($repoName: String!){
  commentAdded(repoFullName: $repoName) {
    id
    content
  }
}

To fix this, we can use the withFilter helper function to control updates on a per-client basis.

Here's an example resolver for commentAdded that uses the withFilter function:

Điều này cho thấy một vấn đề tiềm ẩn: máy chủ của chúng tôi có thể xuất bản sự kiện COMMENT_ADDED bất cứ khi nào nhận xét được thêm vào bất kỳ kho lưu trữ nào. Điều này có nghĩa là trình phân giải commentAdded thực thi mọi nhận xét mới, bất kể nó được thêm vào kho lưu trữ nào. Do đó, khách hàng đăng ký có thể nhận được dữ liệu mà họ không muốn (hoặc thậm chí không nên có quyền truy cập).

Để khắc phục điều này, chúng ta có thể sử dụng chức năng trợ giúp withFilter để kiểm soát các bản cập nhật trên cơ sở từng máy khách.

Đây là một ví dụ về trình phân giải cho commentAdded sử dụng hàm withFilter:

const { withFilter } = require('apollo-server');

const resolvers = {
  Subscription: {

    commentAdded: {
      subscribe: withFilter(
        () => pubsub.asyncIterator('COMMENT_ADDED'),
        (payload, variables) => {
          // Only push an update if the comment is on
          // the correct repository for this operation
          return (payload.commentAdded.repository_name === variables.repoFullName);
        },
      ),
    }
  },
    // ...other resolvers...
};

The withFilter function takes two parameters:

  • The first parameter is exactly the function you would use for subscribe if you weren't applying a filter.

  • The second parameter is a filter function that returns true if a subscription update should be sent to a particular client, and false otherwise (Promise<boolean> is also allowed). This function takes two parameters of its own:

    • payload is the payload of the event that was published.

    • variables is an object containing all arguments the client provided when initiating their subscription.

Use withFilter to make sure clients get exactly the subscription updates they want (and are allowed to receive).

Hàm withFilter nhận hai tham số:

  • Tham số đầu tiên chính xác là hàm bạn sẽ sử dụng để đăng ký nếu bạn không áp dụng bộ lọc.

  • Tham số thứ hai là một hàm bộ lọc trả về true nếu một bản cập nhật đăng ký được gửi đến một ứng dụng khách cụ thể và false nếu không thì (Promise cũng được phép). Hàm này nhận hai tham số của riêng nó:

    • payloadlà trọng tải của sự kiện đã được xuất bản.

    • variables là một đối tượng chứa tất cả các đối số mà khách hàng cung cấp khi bắt đầu đăng ký của họ.

Sử dụng withFilter để đảm bảo khách hàng nhận được chính xác các bản cập nhật đăng ký mà họ muốn (và được phép nhận).

Máy chủ mẫu này hiển thị một đăng ký (numberIncremented) trả về một số nguyên được tăng lên trên máy chủ mỗi giây. Ví dụ này chỉ yêu cầu thư viện apollo-server.

Trong Apollo Studio Explorer, bạn phải chỉ định điểm cuối đăng ký của máy chủ của mình (ws: // localhost: 4000 / subscribe) trong tab Cài đặt Explorer.

const { ApolloServer, PubSub, gql } = require('apollo-server');
const pubsub = new PubSub();
const PORT = 4000;

// Schema definition
const typeDefs = gql`
  type Query {
    currentNumber: Int
  }

  type Subscription {
    numberIncremented: Int
  }
`;

// Resolver map
const resolvers = {
  Query: {
    currentNumber() {
      return currentNumber;
    }
  },
  Subscription: {
    numberIncremented: {
      subscribe: () => pubsub.asyncIterator(['NUMBER_INCREMENTED']),
    },
  }
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
  subscriptions: {
    path: '/subscriptions',
    onConnect: (connectionParams, webSocket, context) => {
      console.log('Client connected');
    },
    onDisconnect: (webSocket, context) => {
      console.log('Client disconnected')
    },
  },
});

let currentNumber = 0;
function incrementNumber() {
  currentNumber++;
  pubsub.publish('NUMBER_INCREMENTED', { numberIncremented: currentNumber });
  setTimeout(incrementNumber, 1000);
}

server.listen().then(({ url }) => {
  console.log(`🚀 Subscription endpoint ready at ws://localhost:${PORT}${server.subscriptionsPath}`)
  console.log('Query at studio.apollographql.com/dev')
});

// Start incrementing
incrementNumber();

Because all operation types use the same context initialization function, you should check which of req or connection is present for each incoming request:

Khi khởi tạo ngữ cảnh cho một truy vấn hoặc đột biến, bạn thường trích xuất tiêu đề HTTP và siêu dữ liệu yêu cầu khác từ đối tượng yêu cầu được cung cấp cho hàm ngữ cảnh.

Đối với đăng ký, bạn trích xuất siêu dữ liệu này từ đối tượng kết nối. Đối tượng này tuân theo giao diện ExecutionParams.

Bởi vì tất cả các loại hoạt động sử dụng cùng một chức năng khởi tạo ngữ cảnh, bạn nên kiểm tra yêu cầu hoặc kết nối nào hiện có cho mỗi yêu cầu đến:

const server = new ApolloServer({
  context: ({ req, connection }) => {
    if (connection) { // Operation is a Subscription
      // Obtain connectionParams-provided token from connection.context
      const token = connection.context.authorization || "";
      return { token };
    } else { // Operation is a Query/Mutation
      // Obtain header-provided token from req.headers
      const token = req.headers.authorization || "";
      return { token };
    }
  },
});

Điều này đặc biệt quan trọng vì siêu dữ liệu như mã thông báo xác thực được gửi khác nhau tùy thuộc vào quá trình vận chuyển.

You can define functions that Apollo Server executes whenever a subscription request connects (onConnect) or disconnects (onDisconnect).

Defining an onConnect function provides the following benefits:

  • You can reject a particular incoming connection by throwing an exception or returning false in onConnect.

  • If onConnect returns an object, that object's fields are added to the WebSocket connection's context object.

Bạn có thể xác định các chức năng mà Apollo Server thực thi bất cứ khi nào yêu cầu đăng ký kết nối (onConnect) hoặc ngắt kết nối (onDisconnect).

Việc xác định chức năng onConnect cung cấp các lợi ích sau:

  • Bạn có thể từ chối một kết nối đến cụ thể bằng cách ném một ngoại lệ hoặc trả về false trong onConnect.

    • Điều này đặc biệt hữu ích cho việc xác thực.

  • Nếu onConnect trả về một đối tượng, các trường của đối tượng đó sẽ được thêm vào đối tượng ngữ cảnh của kết nối WebSocket.

    • Đây không phải là ngữ cảnh hoạt động được truyền giữa các trình phân giải. Tuy nhiên, bạn có thể chuyển các giá trị này từ ngữ cảnh của kết nối khi bạn khởi tạo ngữ cảnh hoạt động.

Bạn cung cấp các định nghĩa hàm này cho phương thức khởi tạo của ApolloServer, như sau:

const server = new ApolloServer(
  subscriptions: {
    onConnect: (connectionParams, webSocket, context) => {
      console.log('Connected!')
    },
    onDisconnect: (webSocket, context) => {
      console.log('Disconnected!')
    },
    // ...other options...
  },
);

Các hàm này được truyền các tham số sau:

connectionParams

Object

Passed to onConnect only.

webSocket

WebSocket

context

ConnectionContext

Context object for the WebSocket connection. This is not the context object for the associated subscription operation.

connectionParams

Object

Chỉ được chuyển cho onConnect.

Một đối tượng chứa các tham số được bao gồm trong yêu cầu, chẳng hạn như mã thông báo xác thực.

Để biết chi tiết, hãy xem Xác thực qua WebSocket trong tài liệu Apollo Client.

webSocket

WebSocket

Kết nối hoặc ngắt kết nối WebSocket.

context

ConnectionContext

Đối tượng ngữ cảnh cho kết nối WebSocket. Đây không phải là đối tượng ngữ cảnh cho hoạt động đăng ký được liên kết. Xem các lĩnh vực

The connectionParams argument in the onConnect callback contains the information passed by the client and can be used to validate user credentials. The GraphQL context can also be extended with the authenticated user data to enable fine grain authorization.

Trên máy khách, SubscriberClient hỗ trợ thêm thông tin mã thông báo vào connectionParams (ví dụ) sẽ được gửi cùng với thông báo WebSocket đầu tiên. Trong máy chủ, tất cả các đăng ký GraphQL bị trì hoãn cho đến khi kết nối được xác thực hoàn toàn và lệnh gọi lại onConnect trả về giá trị trung thực.

Đối số connectionParams trong lệnh gọi lại onConnect chứa thông tin do máy khách chuyển và có thể được sử dụng để xác thực thông tin xác thực của người dùng. Ngữ cảnh GraphQL cũng có thể được mở rộng với dữ liệu người dùng đã xác thực để cho phép ủy quyền hạt mịn.

const { ApolloServer } = require('apollo-server');
const { resolvers, typeDefs } = require('./schema');

const validateToken = authToken => {
  // ... validate token and return a Promise, rejects in case of an error
};

const findUser = authToken => {
  return tokenValidationResult => {
    // ... finds user by auth token and return a Promise, rejects in case of an error
  };
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
  subscriptions: {
    onConnect: (connectionParams, webSocket) => {
      if (connectionParams.authToken) {
        return validateToken(connectionParams.authToken)
          .then(findUser(connectionParams.authToken))
          .then(user => {
            return {
              currentUser: user,
            };
          });
      }

      throw new Error('Missing auth token!');
    },
  },
});

server.listen().then(({ url, subscriptionsUrl }) => {
  console.log(`🚀 Server ready at ${url}`);
  console.log(`🚀 Subscriptions ready at ${subscriptionsUrl}`);
});

Ví dụ trên xác thực mã thông báo của người dùng được gửi cùng với thông báo khởi tạo đầu tiên trên phương tiện truyền tải, sau đó nó tra cứu người dùng và trả về đối tượng người dùng dưới dạng Lời hứa. Đối tượng người dùng được tìm thấy sẽ có sẵn dưới dạng context.currentUser trong các trình phân giải GraphQL của bạn.

Trong trường hợp xảy ra lỗi xác thực, Lời hứa sẽ bị từ chối, điều này ngăn cản kết nối của khách hàng.

Bạn có thể sử dụng đăng ký với bất kỳ tích hợp phần mềm trung gian nào được hỗ trợ của Apollo Server. Để làm như vậy, bạn gọi installSubscriptionHandlers trên phiên bản ApolloServer của mình.

Ví dụ này cho phép đăng ký một máy chủ Express sử dụng apollo-server-express:

const http = require('http');
const { ApolloServer } = require('apollo-server-express');
const express = require('express');

const PORT = 4000;
const app = express();
const server = new ApolloServer({ typeDefs, resolvers });

server.applyMiddleware({app})

const httpServer = http.createServer(app);

server.installSubscriptionHandlers(httpServer);

// Make sure to call listen on httpServer, NOT on app.
httpServer.listen(PORT, () => {
  console.log(`🚀 Server ready at http://localhost:${PORT}${server.graphqlPath}`)
  console.log(`🚀 Subscriptions ready at ws://localhost:${PORT}${server.subscriptionsPath}`)
})

Như đã đề cập ở trên, lớp PubSub không được khuyến nghị cho môi trường sản xuất vì hệ thống xuất bản sự kiện của nó nằm trong bộ nhớ. Điều này có nghĩa là các sự kiện được xuất bản bởi một phiên bản của máy chủ GraphQL của bạn sẽ không nhận được các đăng ký do các phiên bản khác xử lý.

Thay vào đó, bạn nên sử dụng một lớp con của lớp trừu tượng PubSubEngine mà bạn có thể quay lại với một kho dữ liệu bên ngoài như Redis hoặc Kafka.

Sau đây là các thư viện PubSub do cộng đồng tạo cho các hệ thống xuất bản sự kiện phổ biến:

Apollo Server uses a publish-subscribe (pub/sub) model to track events that update active subscriptions. The (included in every apollo-server package) provides the PubSub class as a basic in-memory event bus to help you get started:

This presents a potential issue: our server probably a COMMENT_ADDED event whenever a comment is added to any repository. This means that the commentAdded resolver executes for every new comment, regardless of which repository it's added to. As a result, subscribing clients might receive data they don't want (or shouldn't even have access to).

Sau khi khởi động máy chủ này, bạn có thể chạy thử đăng ký với Apollo Studio Explorer hoặc GraphQL Playground, như được mô tả trong . Bạn sẽ thấy cập nhật giá trị của đăng ký mỗi giây.

When for a query or mutation, you usually extract HTTP headers and other request metadata from the req object provided to the context function.

For subscriptions, you extract this metadata from the connection object instead. This object adheres to the .

This is especially useful for .

This is not the operation context that's passed between resolvers. However, you can transfer these values from the connection's context when you .

An object containing parameters included in the request, such as an .

For details, see in the Apollo Client documentation.

The connecting or disconnecting .

On the client, SubscriptionsClient supports adding token information to connectionParams () that will be sent with the first WebSocket message. In the server, all GraphQL subscriptions are delayed until the connection has been fully authenticated and the onConnect callback returns a truthy value.

, the PubSub class is not recommended for production environments, because its event-publishing system is in-memory. This means that events published by one instance of your GraphQL server are not received by subscriptions that are handled by other instances.

Instead, you should use a subclass of the that you can back with an external datastore such as Redis or Kafka.

Schema definition
Setting a subscription endpoint
Resolving a subscription
The PubSub class
graphql-subscriptions library
Publishing an event
Listening for events
Filtering events
publishes
Basic runnable example
hướng dẫn toàn ngăn xếp
Operation context
initializing context
ExecutionParams interface
onConnect and onDisconnect
authentication
initialize operation context
Example: Authentication with onConnect
example
Using with middleware integrations
Production PubSub libraries
As mentioned above
PubSubEngine abstract class
Redis
Google PubSub
MQTT enabled broker
RabbitMQ
Kafka
Postgres
Google Cloud Firestore
authentication token
Authenticate over WebSocket
WebSocket
See fields