Lưu ý
Cần có ủy quyền mới truy nhập được vào trang này. Bạn có thể thử đăng nhập hoặc thay đổi thư mục.
Cần có ủy quyền mới truy nhập được vào trang này. Bạn có thể thử thay đổi thư mục.
Trong Bắt đầu nhanh này, bạn sẽ tìm hiểu cách thiết lập và chạy API Nền tảng Microsoft Learn, bao gồm các ví dụ để truy xuất các khóa học, lộ trình học tập, mô-đun và chứng chỉ.
Điều kiện tiên quyết
Trước khi bắt đầu, hãy đảm bảo bạn đã cài đặt những thứ sau:
Node.js (phiên bản 18.0.0 trở lên)
- Node.js là thời gian chạy JavaScript cho phép bạn chạy mã JavaScript/TypeScript bên ngoài trình duyệt web. Nó được yêu cầu để thực thi các tập lệnh ví dụ và quản lý các gói thông qua npm (Trình quản lý gói nút).
- Tải xuống từ: https://nodejs.org/
- Xác minh cài đặt:
node --version
dịch vụ Azure CLI
- Giao diện Azure Command-Line (CLI) là một công cụ để quản lý tài nguyên Azure từ dòng lệnh. Trong hướng dẫn này, nó được sử dụng để xác thực danh tính của bạn để các ví dụ có thể thay mặt bạn truy cập API Nền tảng Tìm hiểu.
- Tải xuống từ: https://learn.microsoft.com/cli/azure/install-azure-cli>
- Xác minh cài đặt:
az --version
Tài khoản Azure
- Cần có tài khoản Azure có đăng ký đang hoạt động để xác thực và truy cập API Nền tảng Microsoft Learn. API sử dụng Microsoft Entra ID (trước đây là Azure Active Directory) để xác thực, yêu cầu thông tin đăng nhập Azure hợp lệ. Bạn không mất phí để truy xuất mã thông báo xác thực từ đăng ký Azure của bạn.
- Bạn cần đăng ký Azure đang hoạt động
- Đăng ký tại: https://azure.microsoft.com/free/
Visual Studio Code (tùy chọn)
- Visual Studio Code (mã VS) là một trình soạn thảo mã nhẹ, miễn phí với thiết bị đầu cuối tích hợp, hỗ trợ IntelliSense và TypeScript. Mặc dù bạn có thể sử dụng bất kỳ trình soạn thảo văn bản và thiết bị đầu cuối nào, nhưng Visual Studio Code cung cấp trải nghiệm hợp lý để chạy các ví dụ này.
- Tải xuống từ: https://code.visualstudio.com/
- Xác minh cài đặt: Mở Visual Studio Code và nhấn Ctrl + ' để mở thiết bị đầu cuối tích hợp
Lưu ý
Tất cả các lệnh được viết bên dưới phải được chạy trong thiết bị đầu cuối Git Bash. Bạn có thể sử dụng thiết bị đầu cuối tích hợp của VS Code (nhấn Ctrl +'), Windows PowerShell hoặc Command Prompt.
Thiết lập dự án
Làm theo các bước sau để tạo một dự án mới và cài đặt các phần phụ thuộc cần thiết.
Tạo một thư mục mới cho dự án của bạn và điều hướng đến nó.
mkdir learn-api-examples cd learn-api-examplesKhởi tạo dự án Node.js mới với cài đặt mặc định. Cờ
-ytự động chấp nhận tất cả các giá trị mặc định.npm init -yCài đặt các gói npm cần thiết (
@azure/identityđể xác thực,tsxđể chạy TypeScript trực tiếp,typescripttrình biên dịch và@types/nodecho các định nghĩa kiểu).npm install @azure/identity tsx typescript @types/nodeTạo một tệp mới có tên
examples.tsvà dán mã bên dưới. Điều này bao gồm xác thực tận dụng Thông tin xác thực mặc định Azure và một số ví dụ về khả năng danh mục có sẵn thông qua API Nền tảng Tìm hiểu./** * Microsoft Learn Platform API Examples * API Version: 2023-11-01-preview * Base URL: https://learn.microsoft.com/api/v1 * * Authentication: OAuth2 with scope https://learn.microsoft.com/.default */ import { DefaultAzureCredential } from "@azure/identity"; const API_BASE_URL = "https://learn.microsoft.com/api/v1"; const API_VERSION = "2023-11-01-preview"; // ============================================================================ // AUTHENTICATION HELPER // ============================================================================ async function getAccessToken(): Promise<string> { const credential = new DefaultAzureCredential(); const token = await credential.getToken("https://learn.microsoft.com/.default"); return token.token; } /** * Helper to handle API response with error checking */ async function handleResponse(response: Response, label: string): Promise<void> { if (!response.ok) { const text = await response.text(); console.log(`${label} Error: ${response.status} ${response.statusText}`); console.log("Response:", text || "(empty)"); return; } const text = await response.text(); if (!text) { console.log(`${label}: (empty response)`); return; } try { const data = JSON.parse(text); console.log(`${label}:`, JSON.stringify(data, null, 2)); } catch (e) { console.log(`${label} Parse Error: Invalid JSON`); console.log("Raw response:", text.substring(0, 500)); } } // ============================================================================ // TRAINING ENDPOINTS // ============================================================================ /** * List all courses with optional filters * GET /courses */ async function listCourses(options?: { levels?: string[]; roles?: string[]; products?: string[]; locale?: string; maxpagesize?: number; }): Promise<void> { const token = await getAccessToken(); const params = new URLSearchParams({ "api-version": API_VERSION }); if (options?.levels) params.append("levels", options.levels.join(",")); if (options?.roles) params.append("roles", options.roles.join(",")); if (options?.products) params.append("products", options.products.join(",")); if (options?.locale) params.append("locale", options.locale); if (options?.maxpagesize) params.append("maxpagesize", options.maxpagesize.toString()); const response = await fetch(`${API_BASE_URL}/courses?${params}`, { method: "GET", headers: { "Accept": "application/json", "Authorization": `Bearer ${token}` } }); await handleResponse(response, "Courses"); } /** * Get a specific course by ID * GET /courses/{id} */ async function getCourse(courseId: string, locale?: string): Promise<void> { const token = await getAccessToken(); const params = new URLSearchParams({ "api-version": API_VERSION }); if (locale) params.append("locale", locale); const response = await fetch(`${API_BASE_URL}/courses/${courseId}?${params}`, { method: "GET", headers: { "Accept": "application/json", "Authorization": `Bearer ${token}` } }); await handleResponse(response, "Course"); } /** * List all learning paths * GET /learning-paths */ async function listLearningPaths(options?: { levels?: string[]; roles?: string[]; products?: string[]; subjects?: string[]; locale?: string; maxpagesize?: number; }): Promise<void> { const token = await getAccessToken(); const params = new URLSearchParams({ "api-version": API_VERSION }); if (options?.levels) params.append("levels", options.levels.join(",")); if (options?.roles) params.append("roles", options.roles.join(",")); if (options?.products) params.append("products", options.products.join(",")); if (options?.subjects) params.append("subjects", options.subjects.join(",")); if (options?.locale) params.append("locale", options.locale); if (options?.maxpagesize) params.append("maxpagesize", options.maxpagesize.toString()); const response = await fetch(`${API_BASE_URL}/learning-paths?${params}`, { method: "GET", headers: { "Accept": "application/json", "Authorization": `Bearer ${token}` } }); await handleResponse(response, "Learning Paths"); } /** * Get a specific learning path by ID * GET /learning-paths/{id} */ async function getLearningPath(learningPathId: string, locale?: string): Promise<void> { const token = await getAccessToken(); const params = new URLSearchParams({ "api-version": API_VERSION }); if (locale) params.append("locale", locale); const response = await fetch(`${API_BASE_URL}/learning-paths/${learningPathId}?${params}`, { method: "GET", headers: { "Accept": "application/json", "Authorization": `Bearer ${token}` } }); await handleResponse(response, "Learning Path"); } /** * List all modules * GET /modules */ async function listModules(options?: { levels?: string[]; roles?: string[]; products?: string[]; subjects?: string[]; locale?: string; maxpagesize?: number; }): Promise<void> { const token = await getAccessToken(); const params = new URLSearchParams({ "api-version": API_VERSION }); if (options?.levels) params.append("levels", options.levels.join(",")); if (options?.roles) params.append("roles", options.roles.join(",")); if (options?.products) params.append("products", options.products.join(",")); if (options?.subjects) params.append("subjects", options.subjects.join(",")); if (options?.locale) params.append("locale", options.locale); if (options?.maxpagesize) params.append("maxpagesize", options.maxpagesize.toString()); const response = await fetch(`${API_BASE_URL}/modules?${params}`, { method: "GET", headers: { "Accept": "application/json", "Authorization": `Bearer ${token}` } }); await handleResponse(response, "Modules"); } /** * Get a specific module by ID * GET /modules/{id} */ async function getModule(moduleId: string, locale?: string): Promise<void> { const token = await getAccessToken(); const params = new URLSearchParams({ "api-version": API_VERSION }); if (locale) params.append("locale", locale); const response = await fetch(`${API_BASE_URL}/modules/${moduleId}?${params}`, { method: "GET", headers: { "Accept": "application/json", "Authorization": `Bearer ${token}` } }); await handleResponse(response, "Module"); } /** * Get a specific unit by ID * GET /units/{id} */ async function getUnit(unitId: string, locale?: string): Promise<void> { const token = await getAccessToken(); const params = new URLSearchParams({ "api-version": API_VERSION }); if (locale) params.append("locale", locale); const response = await fetch(`${API_BASE_URL}/units/${unitId}?${params}`, { method: "GET", headers: { "Accept": "application/json", "Authorization": `Bearer ${token}` } }); await handleResponse(response, "Unit"); } // ============================================================================ // CREDENTIALS ENDPOINTS // ============================================================================ /** * List all certifications * GET /certifications */ async function listCertifications(options?: { levels?: string[]; roles?: string[]; products?: string[]; subjects?: string[]; locale?: string; maxpagesize?: number; }): Promise<void> { const token = await getAccessToken(); const params = new URLSearchParams({ "api-version": API_VERSION }); if (options?.levels) params.append("levels", options.levels.join(",")); if (options?.roles) params.append("roles", options.roles.join(",")); if (options?.products) params.append("products", options.products.join(",")); if (options?.subjects) params.append("subjects", options.subjects.join(",")); if (options?.locale) params.append("locale", options.locale); if (options?.maxpagesize) params.append("maxpagesize", options.maxpagesize.toString()); const response = await fetch(`${API_BASE_URL}/certifications?${params}`, { method: "GET", headers: { "Accept": "application/json", "Authorization": `Bearer ${token}` } }); await handleResponse(response, "Certifications"); } /** * Get a specific certification by ID * GET /certifications/{id} */ async function getCertification(certificationId: string, locale?: string): Promise<void> { const token = await getAccessToken(); const params = new URLSearchParams({ "api-version": API_VERSION }); if (locale) params.append("locale", locale); const response = await fetch(`${API_BASE_URL}/certifications/${certificationId}?${params}`, { method: "GET", headers: { "Accept": "application/json", "Authorization": `Bearer ${token}` } }); await handleResponse(response, "Certification"); } /** * List all exams * GET /exams */ async function listExams(options?: { levels?: string[]; roles?: string[]; products?: string[]; locale?: string; maxpagesize?: number; }): Promise<void> { const token = await getAccessToken(); const params = new URLSearchParams({ "api-version": API_VERSION }); if (options?.levels) params.append("levels", options.levels.join(",")); if (options?.roles) params.append("roles", options.roles.join(",")); if (options?.products) params.append("products", options.products.join(",")); if (options?.locale) params.append("locale", options.locale); if (options?.maxpagesize) params.append("maxpagesize", options.maxpagesize.toString()); const response = await fetch(`${API_BASE_URL}/exams?${params}`, { method: "GET", headers: { "Accept": "application/json", "Authorization": `Bearer ${token}` } }); await handleResponse(response, "Exams"); } /** * Get a specific exam by ID * GET /exams/{id} */ async function getExam(examId: string, locale?: string): Promise<void> { const token = await getAccessToken(); const params = new URLSearchParams({ "api-version": API_VERSION }); if (locale) params.append("locale", locale); const response = await fetch(`${API_BASE_URL}/exams/${examId}?${params}`, { method: "GET", headers: { "Accept": "application/json", "Authorization": `Bearer ${token}` } }); await handleResponse(response, "Exam"); } /** * List all applied skills * GET /applied-skills */ async function listAppliedSkills(options?: { levels?: string[]; roles?: string[]; products?: string[]; subjects?: string[]; locale?: string; maxpagesize?: number; }): Promise<void> { const token = await getAccessToken(); const params = new URLSearchParams({ "api-version": API_VERSION }); if (options?.levels) params.append("levels", options.levels.join(",")); if (options?.roles) params.append("roles", options.roles.join(",")); if (options?.products) params.append("products", options.products.join(",")); if (options?.subjects) params.append("subjects", options.subjects.join(",")); if (options?.locale) params.append("locale", options.locale); if (options?.maxpagesize) params.append("maxpagesize", options.maxpagesize.toString()); const response = await fetch(`${API_BASE_URL}/applied-skills?${params}`, { method: "GET", headers: { "Accept": "application/json", "Authorization": `Bearer ${token}` } }); await handleResponse(response, "Applied Skills"); } /** * Get a specific applied skill by ID * GET /applied-skills/{id} */ async function getAppliedSkill(appliedSkillId: string, locale?: string): Promise<void> { const token = await getAccessToken(); const params = new URLSearchParams({ "api-version": API_VERSION }); if (locale) params.append("locale", locale); const response = await fetch(`${API_BASE_URL}/applied-skills/${appliedSkillId}?${params}`, { method: "GET", headers: { "Accept": "application/json", "Authorization": `Bearer ${token}` } }); await handleResponse(response, "Applied Skill"); } // ============================================================================ // PAGINATION HELPER // ============================================================================ /** * Helper to handle paginated responses */ async function fetchAllPages<T>(initialUrl: string, token: string): Promise<T[]> { const allItems: T[] = []; let nextLink: string | undefined = initialUrl; while (nextLink) { const response = await fetch(nextLink, { method: "GET", headers: { "Accept": "application/json", "Authorization": `Bearer ${token}` } }); const data = await response.json(); allItems.push(...data.value); nextLink = data.nextLink; } return allItems; } // ============================================================================ // EXAMPLE USAGE // ============================================================================ async function main() { try { // List beginner-level certifications for Azure console.log("=== Listing Azure certifications (beginner level) ==="); await listCertifications({ levels: ["beginner"], products: ["azure"], maxpagesize: 5 }); // List certifications console.log("\n=== Listing certifications ==="); await listCertifications({ maxpagesize: 5 }); // List all Spanish learning paths console.log("\n=== Listing Spanish learning paths ==="); await listLearningPaths({ locale: "es-es", maxpagesize: 5 }); // Get a specific learning path by ID console.log("\n=== Getting learning path: learn.introduction-ai-azure ==="); await getLearningPath("learn.introduction-ai-azure"); // Get a specific module by ID console.log("\n=== Getting module: learn.wwl.fundamentals-generative-ai ==="); await getModule("learn.wwl.fundamentals-generative-ai"); // Get a specific unit by ID console.log("\n=== Getting unit: learn.wwl.fundamentals-generative-ai.agents ==="); await getUnit("learn.wwl.fundamentals-generative-ai.agents"); // Get a specific applied skill by ID console.log("\n=== Getting applied skill: applied-skill.deploy-and-configure-azure-monitor ==="); await getAppliedSkill("applied-skill.deploy-and-configure-azure-monitor"); // Get a specific certification by ID console.log("\n=== Getting certification: certification.d365-functional-consultant-customer-service ==="); await getCertification("certification.d365-functional-consultant-customer-service"); // Get a specific exam by ID console.log("\n=== Getting exam: exam.77-881 ==="); await getExam("exam.77-881"); // Get a specific instructor-led course by ID console.log("\n=== Getting instructor-led course: course.ai-900t00 ==="); await getCourse("course.ai-900t00"); } catch (error) { console.error("Error:", error); } } main();
Xác thực và chạy các ví dụ
Làm theo các bước sau để xác thực với Azure và chạy mã mẫu.
Đăng nhập vào Azure CLI. Bước này sẽ mở cửa sổ trình duyệt nơi bạn nhập thông tin đăng nhập Azure của mình.
az loginNếu bạn có nhiều gói đăng ký, hãy đặt gói đăng ký đang hoạt động. Thay thế
<your-subscription-name>bằng tên hoặc ID đăng ký của bạn.az account set --subscription "<your-subscription-name>"Xác minh thông tin đăng nhập của bạn có thể truy cập API Nền tảng Learn.
az account get-access-token --resource https://learn.microsoft.comNếu thành công, bạn sẽ thấy phản hồi JSON với một
accessTokentrường.Chạy tệp ví dụ bằng cách sử dụng
npxđể thực thitsxgói.npx tsx examples.ts(Tùy chọn) Lưu đầu ra vào tệp bằng cách sử dụng chuyển hướng đầu ra.
npx tsx examples.ts > output.txt 2>&1
Dọn dẹp tài nguyên
Nếu bạn không còn cần tài nguyên được tạo trong phần bắt đầu nhanh này, bạn có thể xóa chúng.
Xóa thư mục dự án và tất cả nội dung của nó.
cd .. rm -rf learn-api-examplesTrên Windows PowerShell, hãy sử dụng:
cd .. Remove-Item -Recurse -Force learn-api-examples(Tùy chọn) Đăng xuất khỏi Azure CLI để xóa thông tin đăng nhập được lưu trong bộ nhớ cache.
az logout
Lưu ý
Bắt đầu nhanh này không tạo bất kỳ tài nguyên Azure nào phát sinh chi phí. Các lệnh gọi API chỉ sử dụng danh tính Azure hiện có của bạn để xác thực.