cuốn sách gpt4 ai đã làm

Bắt đầu học .NET8 MiniApis

In lại Tác giả: Sahara Thời gian cập nhật: 2024-07-02 21:04:32 58 4
mua khóa gpt4 Nike

Giới thiệu

MiniApis là gì?

Các tính năng và lợi ích của MiniApis

Ứng dụng script của MiniApis

Môi trường cài đặt

System request

Cài đặt MiniApis

Cấu hình môi trường phát triển

cơ sở khái niệm

Tổng quan về kiến ​​trúc MiniApis

Giải thích các thuật ngữ chính (như Endpoint, Handler, vv)

So sánh MiniApis và các API khung khác

Project MiniApis first

Tạo một dự án MiniApis đơn giản

Giới thiệu dự kiến ​​trúc

[Viết Điểm cuối API đầu tiên](##Viết Điểm cuối API đầu tiên)

Chạy và kiểm tra API đầu tiên của bạn

Yêu cầu định tuyến và xử lý

Xác định và quản lý đường tuyến

[Xử lý các loại yêu cầu HTTP khác nhau (GET, POST, PUT, DELETE)](##Xử lý các loại yêu cầu HTTP khác nhau (GET, POST, PUT, DELETE))

Sử dụng tuyến đường tham số và truy vấn tham số

Xử lý dữ liệu

Xử lý yêu cầu dữ liệu (tham số đường dẫn, truy vấn số, nội dung yêu cầu)

Trả về phản hồi dữ liệu

Sử dụng phần mềm trung gian để xử lý dữ liệu

Xử lý lỗi

Bắt và xử lý lỗi

Tùy chỉnh lỗi phản hồi

Sử dụng phần mềm trung gian để xử lý lỗi

Xác thực và bảo mật dữ liệu

[Phương pháp xác minh dữ liệu](##Phương pháp xác minh dữ liệu)

Các phương pháp hay nhất để bảo mật API

Xác thực và ủy quyền

Tương tác với cơ sở dữ liệu

Kết nối với cơ sở dữ liệu

Thực hiện các thao tác cơ bản CRUD

Use tool ORM (Ánh xạ quan hệ đối tượng)

Tính năng nâng cao

Việc sử dụng và viết phần mềm trung gian

Tải lên và tải xuống tập tin

Triển khai kiểm tra API phiên bản

Kiểm tra và gỡ lỗi

Viết bài kiểm tra đơn vị và bài kiểm tra hợp lý

Use debug tool

Hiệu suất tối ưu hóa

Triển khai ứng dụng MiniApis

Triển khai tới local server

[Triển khai lên nền tảng đám mây (chẳng hạn như AWS, Azure, Heroku, vv)](##Triển khai lên nền tảng đám mây (chẳng hạn như AWS, Azure, Heroku, vv))

Tích hợp liên tục và phát triển khai liên tục (CI/CD)

Thực hiện dự kiến

Dự án 1: Xây dựng API quản lý tác vụ đơn giản

Dự án 2: Xây dựng người dùng xác thực hệ thống

Dự án thứ ba: Xây dựng Blog API

Câu hỏi và giải pháp thường gặp

Các lỗi và giải pháp thường gặp

Các phương pháp hay nhất trong phát triển MiniApis

nguồn năng lượng và cộng đồng

Chính thức tài liệu và tài nguyên

Diễn đàn cộng đồng và thảo luận nhóm

Tài liệu được xuất bản để nghiên cứu thêm

1. Giới thiệu: Thế giới kỳ diệu của MiniAPI

Đây là các pháp sư mã hóa đồng nghiệp! (bàn phím) của bạn, chúng tôi sắp bắt đầu một cuộc hành trình tuyệt vời .

MiniAPI là gì?

Hãy tưởng tượng nếu bạn có thể tạo một API mạnh mẽ chỉ bằng một vài dòng mã. Đây chính là điều kỳ diệu của MiniAPI! MiniAPIs là một sự nhẹ nhõm trong ASP.NET Core cho phép chúng tôi tạo API HTTP với mã hóa và cấu hình tối thiểu.

Nói một cách đơn giản, MiniAPI tương tự như cài đặt một siêu máy tính vào web ứng dụng của bạn để bạn có thể xây dựng nhanh chóng. Hiệu suất API cuối cùng cao hơn mà không cần xử lý số lượng trình chỉnh sửa lớn có sẵn trong hệ thống truyền tải ASP.NET MVC ứng dụng.

Các tính năng và lợi ích của MiniAPI

  1. Đơn giản và rõ ràng: Sử dụng MiniAPI, bạn có thể tạo một API hoàn chỉnh với rất ít mã hóa. Không có bộ điều khiển, không có cấu hình. cấu hình phức tạp tuyến tính, mọi thứ đều rất đơn giản.

  2. Hiệu suất tuyệt vời: Thực hiện thiết kế rút gọn nên MiniAPI chạy rất nhanh. Nó cắt bỏ lớp giữa và xử lý các yêu cầu HTTP trực tuyến tiếp theo, giúp bạn phản hồi API của bạn như chớp.

  3. Linh hoạt: MiniAPI hỗ trợ nhiều phương thức HTTP khác nhau (GET, POST, PUT, DELETE, vv) và có thể dễ dàng xử lý các loại yêu cầu và phản hồi khác nhau.

  4. Dễ học và sử dụng: Nếu bạn đã quen thuộc với C# và ASP.NET Core, việc sử dụng MiniAPI thành công sẽ rất dễ dàng ngay cả khi bạn sử dụng. người mới, API trực tiếp của nó sẽ cho phép bạn bắt đầu nhanh chóng.

  5. Tích hợp hoàn hảo với hệ sinh thái ASP.NET Core: MiniAPI hoạt động trơn tru với các tính năng ASP.NET Core khác như chèn phụ thuộc, phần mềm trung gian, vv

Ứng dụng script của MiniAPI

Đơn giản MiniAPI được thiết kế riêng cho các vấn đề sau:

  1. Vi dịch vụ: Khi bạn cần nhanh chóng xây dựng các dịch vụ nhẹ nhàng, MiniAPI là cánh tay phải của bạn. Nó có thể giúp bạn tạo ra các dịch vụ. thành công của dịch vụ độc lập, hiệu quả.

  2. Mini API cho phép bạn xây dựng một mô hình hoạt động trong vài phút.

  3. Ứng dụng CRUD đơn giản: MiniAPI cung cấp một cách nhanh chóng để phát triển các hoạt động CRUD (tạo, đọc, cập nhật, xóa) cơ bản bản không yêu cầu logic nghiệp vụ phức tạp.

  4. Bạn có thể dễ dàng tạo ra các hàm đáp ứng API.

  5. Giao tiếp thiết bị IoT: Cung cấp thiết bị IoT, MiniAPI giải pháp chi phí thấp.

API nhỏ:

var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/hello", () => "Xin chào, MiniAPIs World!");

Thực sự đơn giản! Một vài dòng mã này tạo ra API cuối cùng trả về "Xin chào, MiniAPIs World!"

API Web API Web API dự án lớn tiếp theo hay chỉ muốn phát triển ý tưởng một cách nhanh chóng, MiniAPI có thể là đồng minh đạt năng lực của bạn.

Bạn đã có Mini API và tạo ra các API tuyệt vời. sẵn sàng chưa? Hãy tiếp tục cuộc hành trình của chúng tôi!

2. Thiết lập môi trường: Chuẩn bị cho bất kỳ hoạt động nào của MiniAPI

Chào mừng bạn đến với các MiniAPI học thuật được phép của chúng tôi! mình, chúng ta cần chuẩn bị sẵn hộp công cụ ma thuật của mình. một nhà phát triển tốt nhất cần có môi trường phát triển phù hợp. sử dụng MiniAPI!

System request

API nhỏ:

  1. hệ điều hành:

    • Windows 10 trở lên
    • macOS 10.15 (Catalina) trở lên
    • Các bản phân phối chính Linux khác nhau (chẳng hạn như Ubuntu 18.04+, Fedora 33+, Debian 10+)
  2. Phần cứng yêu cầu:

    • RAM tối thiểu 4GB (khuyến nghị 8GB trở lên)
    • 10GB
    • bộ xử lý 64-bit

Mặc dù đây là những yêu cầu tối thiểu nhưng hãy nhớ rằng phần cứng hơn sẽ giúp trải nghiệm phát triển của bạn mịn hơn.

Cài đặt MiniAPI

Mini API thực sự là một phần của ASP.NET Core, vì vậy chúng tôi chỉ cần cài đặt .NET SDK dưới đây là các bước cài đặt:

  1. Tải xuống .NET SDK: Truy cập trang tải xuống .NET chính thức (https://dotnet.microsoft.com/download) và tải xuống phiên bản .NET SDK mới nhất. bản phù hợp với hệ điều hành của bạn.

  2. Cài đặt .NET SDK: Quá trình cài đặt đã được tải xuống và làm theo lời nhắc để hoàn tất quá trình cài đặt. cài đặt bình thường và chỉ cần nhấp vào "Tiếp theo" một vài lần.

  3. Xác minh trình cài đặt: Sau khi quá trình cài đặt hoàn tất, hãy mở lệnh dòng công cụ của bạn (Lệnh dấu nhắc hoặc PowerShell trên Windows, Terminal trên macOS hoặc Linux) và chạy lệnh sau:

    dotnet --version
    

    Nếu quá trình cài đặt thành công, bạn sẽ thấy số phiên bản cài đặt .NET đã cài đặt.

  4. Cài đặt công cụ phát triển: Mặc dù bạn có thể sử dụng bất kỳ trình soạn thảo văn bản nào để mã hóa MiniAPI nhưng tôi thực sự khuyên bạn nên sử dụng Visual Studio hoặc Visual Studio Code. khác, có thể cải thiện đáng kể hiệu quả phát triển của bạn.

    • Visual Studio: https://visualstudio.microsoft.com/
    • Mã Visual Studio: https://code.visualstudio.com/

Cấu hình môi trường phát triển

Bây giờ chúng tôi đã cài đặt các công cụ cần thiết, hãy định cấu hình môi trường phát triển môi trường của chúng tôi:

  1. Điều này thường xảy ra DOTNET_ROOT trỏ đến thư mục cài đặt .NET của bạn. được thực thi tự động trong quá trình cài đặt, nhưng bạn cần phải thiết lập thủ công nếu có thể gặp sự cố.

  2. Visual Studio Code, tôi khuyên bạn nên cài đặt tiện ích mở rộng tiện ích sau:

    • C# cho Visual Studio Code (được OmniSharp hỗ trợ)
    • Trình thử nghiệm .NET cơ bản
    • Trình quản lý gói NuGet
  3. Tạo dự án đầu tiên của bạn: Mở một dòng lệnh, điều hướng đến thư mục mà bạn muốn tạo và chạy dự án command sau:

    web dotnet mới -n MyFirstMiniAPI
    

    Điều này sẽ tạo ra một MiniAPIs dự án mới.

  4. Dự án mở: Mở dự án bạn vừa tạo bằng IDE bạn chọn.

    mã MyFirstMiniAPI
    
  5. Chạy dự án: Trong dự án thư mục, hãy chạy lệnh sau để khởi động ứng dụng MiniAPIs của bạn:

    run dotnet
    

    URL (thường là http://localhost:5000).

Cảm giác như một được phép mạnh mẽ để phát triển điều này phải không?

Don't test và trải nghiệm.

Bạn đã sẵn sàng bắt đầu bất kỳ hoạt động nào của mình với MiniAPI chưa? tuyệt vời hơn nữa!

3. Khái niệm cơ bản: Khám phá bí mật của MiniAPI

Các API nhỏ của chúng tôi ngày nay, chúng tôi sẽ tiết lộ bí mật của MiniAPI và hiểu sâu hơn về khái niệm cốt lõi của nó. cơ bản là rất quan trọng để thành thạo các kỹ năng nâng cao kỹ thuật. một chiều sâu tuyệt vời trong MiniAPI!

Tổng quan về kiến ​​trúc MiniAPI

MiniAPI được thiết kế đơn giản, nhẹ nhàng và hiệu quả. chứa trong hệ thống truyền tải kiến ​​trúc MVC (Model-View-Controller). tạp thì MiniAPI là một câu thần chú đơn giản và mạnh mẽ.

Kiến trúc cốt lõi của bao MiniAPI bao gồm các thành phần chính sau:

  1. Web ứng dụng: Đây là điểm vào và máy chủ của toàn bộ ứng dụng. Trung gian và định tuyến.

  2. Điểm cuối: Đây là điểm cuối của API, nơi xử lý các công cụ HTTP yêu cầu.

  3. Trình xử lý: Đây là yêu cầu xử lý thực thi chức năng và tạo ra phản hồi.

  4. Middleware: Các thành phần này xử lý các yêu cầu trước và sau khi chúng được xử lý.

Giải thích các thuật ngữ chính

Hãy xem xét các khái niệm chính chi tiết hơn:

  1. Điểm cuối: Trong MiniAPI, điểm cuối là URL đường dẫn cụ thể được liên kết với phương thức HTTP (chẳng hạn như GET, POST, ĐẶT, XÓA, v.v.).

    app.MapGet("/hello", () => "Xin chào thế giới!");
    

    Ở đây, "/hello" là điểm đáp ứng cuối cùng của các yêu cầu GET.

  2. Trình xử lý (bộ xử lý): Trình xử lý là hàm nhận các yêu cầu HTTP và trả về các phản hồi trong MiniAPI, trình xử lý có thể là đơn lambda biểu thức. giản hoặc một phương thức được xác định riêng.

    app.MapGet("/users/{id}", (int id) => $"ID người dùng: {id}");
    

    Ở đây, (int id) => $"User ID: {id}" là một trình xử lý.

  3. Middleware: Middleware là thành phần có thể xử lý các yêu cầu và phản hồi. Họ có thể thực hiện các thao tác trước khi yêu cầu đến trình xử lý hoặc có thể sửa đổi phản hồi sau khi trình xử lý đã xử lý yêu cầu. Ví dụ: bạn có thể sử dụng phần mềm trung gian để xử lý xác thực, ghi nhật ký hoặc xử lý ngoại lệ.

  4. Định tuyến: Định tuyến là quá trình ánh xạ các yêu cầu HTTP đến tới các trình xử lý tương ứng. Trong MiniAPI, các tuyến đường thường được xác định thông qua các phương thức Map, chẳng hạn như MapGet, MapPost, v.v.

  5. Tính năng tiêm phụ thuộc: MiniAPI hỗ trợ đầy đủ hệ thống tiêm phụ thuộc của ASP.NET Core. Điều này cho phép bạn dễ dàng quản lý vòng đời và các phần phụ thuộc của dịch vụ.

MiniAPI so với các khung API khác

Chúng ta hãy xem MiniAPI khác với một số khung API phổ biến khác như thế nào:

  1. so với ASP.NET Core MVC truyền thống:

    • MiniAPI nhẹ hơn và không có khái niệm về bộ điều khiển.
    • Mã đơn giản hơn và phù hợp với các dự án nhỏ hoặc dịch vụ vi mô.
    • Thời gian khởi động ngắn hơn và hiệu suất cao hơn một chút.
  2. so với Express.js (Node.js):

    • MiniAPI cung cấp cú pháp ngắn gọn tương tự.
    • MiniAPI được hưởng lợi từ hệ thống loại mạnh mẽ và hiệu suất tốt hơn của .NET.
    • Express.js có lẽ phong phú hơn về hệ sinh thái và hỗ trợ cộng đồng.
  3. so với Bình (Python):

    • Cả hai đều cung cấp những cách đơn giản và trực quan để tạo API.
    • MiniAPI thường hoạt động tốt hơn khi xử lý các yêu cầu đồng thời.
    • Bình có thể tốt hơn một chút trong việc tạo mẫu nhanh.
  4. so với FastAPI (Python):

    • Cả hai đều tập trung vào hiệu suất và sự đơn giản.
    • FastAPI có hỗ trợ OpenAPI (Swagger) tích hợp, trong khi MiniAPI yêu cầu cấu hình bổ sung.
    • MiniAPI được hưởng lợi từ hệ thống kiểu mạnh mẽ và hiệu suất cao của .NET.

Nhìn chung, MiniAPI đạt được sự cân bằng tốt giữa tính đơn giản và hiệu suất. Nó đặc biệt phù hợp với các dự án yêu cầu phát triển nhanh và hiệu suất cao nhưng không muốn bị ràng buộc bởi các khuôn khổ phức tạp.

Bây giờ, bạn đã hiểu kiến trúc cơ bản và các khái niệm cốt lõi của MiniAPI. Kiến thức này sẽ tạo nền tảng vững chắc để bạn nghiên cứu sâu về MiniAPI trong các chương sau. Hãy nhớ rằng, giống như học bất kỳ phép thuật mới nào, việc hiểu lý thuyết cơ bản là rất quan trọng để thành thạo các kỹ thuật nâng cao.

Sẵn sàng để chuyển sang cấp độ tiếp theo? Trong chương tiếp theo, chúng ta sẽ tạo dự án MiniAPIs đầu tiên của mình! Hãy tiếp tục cuộc hành trình kỳ diệu của chúng ta! .

4. Dự án MiniAPIs đầu tiên: bắt đầu hành trình kỳ diệu của bạn

Chào mừng bạn đến với Chương 4 của Khóa học ma thuật MiniAPIs của chúng tôi! Bây giờ chúng ta đã hiểu các khái niệm cơ bản về MiniAPI, đã đến lúc tạo dự án đầu tiên. Giống như một thuật sĩ mới vào nghề vẫy cây đũa thần lần đầu tiên, hôm nay chúng ta sẽ tạo một ứng dụng MiniAPIs đơn giản nhưng đầy đủ chức năng. Hãy thắt dây an toàn, chúng ta sẽ bắt đầu viết mã! .

Tạo một dự án MiniAPIs đơn giản

Đầu tiên, hãy tạo một dự án MiniAPIs mới. Mở công cụ dòng lệnh của bạn, điều hướng đến thư mục mà bạn muốn tạo dự án và chạy lệnh sau:

dotnet web mới -n MyFirstMiniAPI cd MyFirstMiniAPI

Lệnh này tạo một dự án MiniAPIs mới và vào thư mục dự án. Bây giờ, hãy mở trình soạn thảo mã yêu thích của bạn (cá nhân tôi khuyên dùng Visual Studio Code) để xem cấu trúc dự án.

Giới thiệu dự kiến ​​trúc

Sau khi mở dự án, bạn sẽ thấy cấu trúc tệp sau:

MyFirstMiniAPI/ ├── Properties/ │ └── launchSettings.json ├── appssettings.json ├── appssettings.Development.json ├── Program.cs ├── MyFirstMiniAPI.csproj

Hãy hiểu ngắn gọn chức năng của từng tệp:

  • Chương trình.cs: Đây là điểm vào ứng dụng và chứa cấu hình ứng dụng chính và định nghĩa tuyến đường.
  • cài đặt ứng dụng.jsonappsinstall.Development.json: Các tệp này chứa cài đặt cấu hình của ứng dụng.
  • MyFirstMiniAPI.csproj: Đây là tệp dự án xác định các phần phụ thuộc của dự án và các cài đặt khác.
  • Thuộc tính/launchSettings.json: Tệp này xác định các cài đặt về cách khởi chạy ứng dụng.

Viết Điểm cuối API đầu tiên

Bây giờ hãy mở tệp Program.cs. Bạn sẽ thấy một số mã được tạo trước. Chúng tôi sẽ sửa đổi tệp này để tạo điểm cuối API đầu tiên của chúng tôi.

Thay thế nội dung của Program.cs bằng đoạn mã sau:

var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => "Chào mừng bạn đến với MiniAPI đầu tiên của tôi!"); name}", (tên chuỗi) => $"Xin chào, {name}!"); app.MapPost("/echo", async (Yêu cầu httpRequest) => { sử dụng var reader = new StreamReader(request.Body); var body = chờ đọc.ReadToEndAsync(); return $"Bạn đã nói: {body}" });

Hãy giải thích mã này:

  1. Chúng tôi đã tạo một ứng dụng web cơ bản.
  2. Chúng tôi xác định ba điểm cuối:
    • GET "/": Trả lại tin nhắn chào mừng
    • NHẬN "/hello/{name}": chấp nhận tham số tên và trả về lời chào được cá nhân hóa
    • POST "/echo": Đọc nội dung yêu cầu và trả về nội dung của nó dưới dạng phản hồi

Chạy và kiểm tra API đầu tiên của bạn

Bây giờ, hãy chạy API của chúng tôi và kiểm tra nó. Từ dòng lệnh, đảm bảo bạn đang ở trong thư mục dự án, sau đó chạy:

run dotnet

Bạn sẽ thấy đầu ra tương tự như thế này:

thông tin: Microsoft.Hosting.Lifetime[14] Hiện đang nghe: https://localhost:7001 thông tin: Microsoft.Hosting.Lifetime[14] Hiện đang nghe: http://localhost:5000

Bây giờ API của chúng tôi đang chạy! Hãy kiểm tra điểm cuối của chúng tôi bằng cách sử dụng Curl (nếu không có Curl, bạn có thể sử dụng trình duyệt hoặc bất kỳ công cụ kiểm tra API nào):

  1. Kiểm tra đường dẫn gốc:

    cuộn tròn http://localhost:5000/
    

    Kết quả mong đợi: Chào mừng bạn đến với MiniAPI đầu tiên của tôi.

  2. Kiểm tra yêu cầu GET với các tham số:

    cuộn tròn http://localhost:5000/hello/MiniAPIs
    

    Đầu ra dự kiến: Xin chào, MiniAPIs.

  3. Kiểm tra yêu cầu POST:

    Curl -X POST -d "Học MiniAPI thật thú vị!" http://localhost:5000/echo
    

    Kết quả mong đợi: Bạn đã nói: Học MiniAPI rất thú vị.

Có cảm giác như bạn vừa được phép sử dụng thuật toán đầu tiên của mình phải không?

API nhỏ. Chỉ với một vài dòng mã, chúng tôi đã tạo một API. Đầy đủ chức năng có thể xử lý các loại HTTP yêu cầu khác nhau, chấp nhận tham số và trả lời phản hồi.

Trong các chương trình tiếp theo, chúng tôi sẽ đi sâu vào các tính năng nâng cao cao hơn như định tuyến, xác thực dữ liệu, xử lý lỗi, vv Nhưng bây giờ, hãy dành chút thời gian để chúc mừng thành công đầu tiên của bạn! trở thành bậc thầy về MiniAPI.

Hãy nhớ rằng, giống như học bất kỳ kỹ năng mới nào, thực hành là chìa khóa. điểm cuối cùng hoặc thay đổi hành động của điểm cuối cùng có. được sự kỳ diệu của MiniAPI.

Bạn đã sẵn sàng tìm hiểu sâu hơn về thế giới MiniAPI chưa? Trong chương trình tiếp theo, chúng tôi sẽ học cách xử lý tuyến tính Hãy tiếp tục cuộc hành trình bất kỳ của chúng tôi!

5. API nhỏ

Chào mừng bạn đến với Chương 5 về Khóa học ma thuật MiniAPIs của chúng tôi! Hôm nay, chúng tôi sẽ đi sâu vào định tuyến và xử lý yêu cầu trong MiniAPI. thuật toán trong lâu đài, hướng dẫn các yêu cầu đến đích chính xác. các yêu cầu từ mọi hướng .

Xác định và quản lý đường tuyến

Trong MiniAPI đường khác nhau:

Basic tuyến định

Định nghĩa tuyến đường đơn giản nhất như sau:

app.MapGet("/hello", () => "Xin chào thế giới!");

Tuyến đường này sẽ đáp ứng các yêu cầu GET cho /hello.

Tuyến đường có tham số

Bạn có thể bao gồm các tham số trong đường tuyến:

app.MapGet("/users/{id}", (int id) => $"ID người dùng: {id}");

Tuyến đường này sẽ phù hợp với các đường dẫn như /users/1, /users/42, vv và chuyển id làm tham số cho hàm xử lý.

Các tùy chọn tham số và mặc định giá trị

Bạn cũng có thể xác định các tùy chọn tham số và mặc định giá trị:

app.MapGet("/greet/{name?}", (string? name = "Guest") => $"Xin chào, {name}!");

Tuyến đường này có thể phù hợp với /greet/Alice hoặc /greet (tên mặc định là "Khách" trong trường hợp này).

Sử dụng truy vấn tham số

Ngoài đường dẫn tham số, bạn cũng có thể sử dụng truy vấn tham số:

app.MapGet("/search", (string? q, int? page = 1) => $"Đang tìm kiếm '{q}' trên trang {page}");

Tuyến đường này có thể xử lý các yêu cầu như /search?q=dotnet&page=2.

Xử lý các loại HTTP yêu cầu khác nhau

MiniAPI cung cấp một cách dễ dàng để xử lý các phương thức HTTP khác nhau:

NHẬN YÊU CẦU

Chúng thường được sử dụng để lấy dữ liệu:

app.MapGet("/api/products", () => new[] { "Product1", "Product2", "Product3" });

Yêu cầu ĐĂNG

POST yêu cầu thường được sử dụng để tạo mới tài nguyên:

app.MapPost("/api/products", (Sản phẩm sản phẩm) => { // Thêm sản phẩm vào cơ sở dữ liệu return Results.Created($"/api/products/{product.Id}", sản sản phẩm });

PUT yêu cầu

Yêu cầu PUT được sử dụng để cập nhật các tài nguyên hiện có:

app.MapPut("/api/products/{id}", (int id, Product Product) => { // Cập nhật kết quả trả về sản phẩm.NoContent(); });

request XÓA

Yêu cầu DELETE được sử dụng để xóa tài nguyên:

app.MapDelete("/api/products/{id}", (int id) => { // Xóa kết quả trả về sản phẩm.Ok(); });

Sử dụng tuyến đường tham số và truy vấn tham số

Chúng tôi đã biết cách sử dụng tham số trong các đường tuyến, nhưng hãy tìm hiểu sâu hơn một chút:

định tuyến số

Đường dẫn tuyến số tham số là một phần của URL đường dẫn:

app.MapGet("/api/users/{id}/posts/{postId}", (int id, int postId) => $"Đang tìm tải bài đăng {postId} cho người dùng {id}");

Tuyến đường này sẽ phù hợp với các yêu cầu như /api/users/5/posts/10.

truy vấn tham số

Tham số truy vấn là phần sau trong URL:

app.MapGet("/api/products", (string? Category, int? minPrice, int? maxPrice) => { // Sử dụng các tham số này để lọc sản phẩm trả về $"Đang tìm tải sản phẩm sản phẩm trong danh mục {category}," + $"phạm vi giá: {minPrice ?? 0} - {maxPrice ?? int.MaxValue}"; });

/api/products?category=electronics&minPrice=100&maxPrice=500.

Sử dụng kết hợp

Bạn có thể kết hợp các đường dẫn tuyến tham số và truy vấn số trong cùng một đường tuyến:

app.MapGet("/api/users/{userId}/orders", (int userId, DateTime? from, DateTime? to) => { return $"Đang tìm tải đơn hàng cho người dùng {userId}," + $ "từ {từ ?.ToString("yyyy-MM-dd") ?? "sự khởi đầu"} " + $"đến {to?.ToString("yyyy-MM-dd") ?? "Show nay"}"; });

Tuyến đường này có thể xử lý các yêu cầu tương tự như /api/users/42/orders?from=2023-01-01&to=2023-06-30.

Bài tập thực hành: Xây dựng API quản lý thư viện đơn giản

Vui lòng áp dụng những gì chúng tôi đã học vào thực tế và tạo một thư viện đơn giản quản lý API:

var builder = WebApplication.CreateBuilder(args); var app = builder.Build() var books = Danh sách mới(); MapGet("/api/books/{id}", (int id) => books.FirstOrDefault(b => b.Id == id) là Sách ? Results.Ok(book) : Results.NotFound ()); app.MapPost("/api/books", (Sách sách) => { book.Id = books.Count + 1; books.Add(book); return Results.Created($"/api/books/{book.Id}", book }); app.MapPut("/api/books/{id}", (int id, Sách được cập nhật) => { var book = books.FirstOrDefault(b => b.Id == id if (book ==); null) trả về Results.NotFound(); Results.NoContent() }); app.MapDelete("/api/books/{id}", (int id) => { var book = books.FirstOrDefault(b => b.Id == id); if (book == null) return Results.NotFound() ); chuỗi công khai Tiêu đề { set } chuỗi công khai Tác giả { get;

API này cho phép bạn thực hiện các thao tác CRUD cơ bản: liệt kê tất cả sách, lấy một cuốn sách cụ thể, thêm sách mới, cập nhật sách hiện có và xóa sách.

Với ví dụ này, bạn có thể thấy MiniAPI có thể dễ dàng xử lý các loại thông số và yêu cầu HTTP khác nhau như thế nào. Cách tiếp cận ngắn gọn và mạnh mẽ này giúp việc tạo API RESTful cực kỳ dễ dàng.

Hãy nhớ rằng, giống như thành thạo bất kỳ phép thuật nào, luyện tập sẽ tạo nên sự hoàn hảo. Hãy thử sửa đổi ví dụ này, thêm chức năng mới hoặc tạo API của riêng bạn. Khám phá và thử nghiệm là cách tốt nhất để trở thành bậc thầy về MiniAPI.

Trong chương tiếp theo, chúng ta sẽ đi sâu vào xử lý và xác thực dữ liệu. Bạn đã sẵn sàng chưa? Hãy tiếp tục cuộc hành trình kỳ diệu của chúng tôi với MiniAPIs! .

6. Xử lý dữ liệu: sự biến đổi kỳ diệu của MiniAPI

Chào mừng bạn đến với Chương 6 của Khóa học ma thuật MiniAPIs của chúng tôi! Hôm nay, chúng ta sẽ đi sâu vào việc xử lý dữ liệu trong MiniAPI. Hãy tưởng tượng nếu API của bạn là một hội thảo kỳ diệu và việc xử lý dữ liệu là sự biến đổi của bạn, biến dữ liệu thô thành thông tin hữu ích. Hãy cùng nhau học cách làm chủ phép thuật mạnh mẽ này! .

Xử lý dữ liệu yêu cầu

Trong MiniAPI, xử lý dữ liệu từ máy khách là một nhiệm vụ phổ biến. Chúng ta sẽ khám phá cách xử lý các loại dữ liệu đầu vào khác nhau.

tham số đường dẫn

Chúng ta đã thấy cách xử lý các tham số đường dẫn trong các chương trước, nhưng hãy đi sâu hơn một chút:

app.MapGet("/api/users/{id:int}", (int id) => $"ID người dùng: {id}");

Ở đây, :int là một ràng buộc định tuyến, đảm bảo rằng id phải là số nguyên. Bạn có thể sử dụng các ràng buộc khác như :guid, :bool, :datetime, v.v.

truy vấn tham số

Các tham số truy vấn có thể được sử dụng trực tiếp làm tham số phương thức:

app.MapGet("/api/search", (string? query, int? page, int? pageSize) => { return $"Searching for '{query}', Page: {page ?? 1}, PageSize: { kích thước trang ?? 10}"; });

Điểm cuối này có thể xử lý các yêu cầu như /api/search?query=dotnet&page=2&pageSize=20.

Nội dung yêu cầu

Đối với các yêu cầu POST và PUT, bạn thường cần xử lý dữ liệu trong phần nội dung yêu cầu. MiniAPI có thể tự động liên kết các nội dung yêu cầu JSON với các đối tượng C#:

app.MapPost("/api/users", (User user) => { // Xử lý dữ liệu người dùng trả về Results.Created($"/api/users/{user.Id}", user); }); Người dùng { public int Id { get; set; } Tên chuỗi công khai { get; } chuỗi email công khai { get;

Khi bạn gửi nội dung yêu cầu JSON đến điểm cuối này, MiniAPI sẽ tự động giải tuần tự hóa nội dung đó thành đối tượng Người dùng.

Tải tập tin lên

Xử lý việc upload file cũng đơn giản:

app.MapPost("/api/upload", async (tệp IFormFile) => { if (file.Length > 0) { var path = Path.Combine(Directory.GetCurrentDirectory(), "uploads", file.FileName); sử dụng varstream = new FileStream(path, FileMode.Create); đang chờ file.CopyToAsync(stream); Results.Ok($"Tệp {file.FileName} được tải lên thành công." } return Results.BadRequest("Tệp trống." });

Điểm cuối này có thể xử lý việc tải tệp lên và lưu tệp vào thư mục "tải lên" của máy chủ.

Trả về phản hồi dữ liệu

MiniAPI cung cấp nhiều cách để trả lại dữ liệu cho khách hàng.

Trả lại đối tượng trực tiếp

Cách đơn giản nhất là trả về trực tiếp một đối tượng và MiniAPI sẽ tự động tuần tự hóa nó thành JSON:

app.MapGet("/api/users/{id}", (int id) => Người dùng mới { Id = id, Name = "John Doe", Email = "john@example.com" });

Sử dụng IResult

Đối với các phản hồi phức tạp hơn, bạn có thể sử dụng giao diện IResult:

app.MapGet("/api/users/{id}", (int id) => { if (id <= 0) return Results.BadRequest("ID người dùng không hợp lệ"); var user = GetUserById(id); if (người dùng == null) trả về Results.NotFound($"Không tìm thấy người dùng có ID {id}"); trả về Results.Ok(user });

Lớp Results cung cấp nhiều phương thức khác nhau để tạo các loại phản hồi HTTP khác nhau.

phản hồi tùy chỉnh

Bạn cũng có toàn quyền kiểm soát phản hồi HTTP:

app.MapGet("/api/download", () => { var bytes = System.IO.File.ReadAllBytes("somefile.pdf"); trả về Results.File(bytes, "application/pdf", "report. pdf"); });

Ví dụ này cho thấy cách trả lại tệp đã tải xuống.

Sử dụng phần mềm trung gian để xử lý dữ liệu

Middleware có thể xử lý dữ liệu trước hoặc sau khi yêu cầu đến trình xử lý của bạn. Điều này rất hữu ích để thực hiện các mối quan tâm xuyên suốt như ghi nhật ký, xác thực, v.v.

Tạo phần mềm trung gian tùy chỉnh

Đây là một ví dụ về phần mềm trung gian ghi nhật ký đơn giản:

app.Use(async (context, next) => { var start = DateTime.UtcNow; chờ tiếp theo(); var thời lượng = DateTime.UtcNow - start; Console.WriteLine($"Yêu cầu {context.Request.Path} đã mất {duration.TotalMilliseconds}ms"); });

Middleware này sẽ ghi lại thời gian xử lý của từng yêu cầu.

Sử dụng phần mềm trung gian tích hợp

ASP.NET Core cung cấp một số phần mềm trung gian tích hợp sẵn mà bạn có thể sử dụng với MiniAPI:

app.UseHttpsRedirection(); app.UseAuthentication();

Các phần mềm trung gian này được sử dụng để chuyển hướng, xác thực và ủy quyền HTTPS tương ứng.

Bài tập thực hành: Xây dựng API việc cần làm

Hãy áp dụng những gì chúng ta đã học vào thực tế và tạo một API việc cần làm đơn giản:

var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); var todos = new List(); app.MapGet("/api/todos", () => todos); MapGet("/api/todos/{id}", (int id) => todos.FirstOrDefault(t => t.Id == id) là Todo todo ? Results.Ok(todo) : Results.NotFound()); app.MapPost("/api/todos", (Todo todo) => { todo.Id = todos.Count + 1; todos.Add(todo); trả về Results.Created($"/api/todos/{todo.Id}", todo }); app.MapPut("/api/todos/{id}", (int id, TodoupdateTodo) => { var todo = todos.FirstOrDefault(t => t.Id == id); if (todo == null) trả về Results.NotFound(); todo.Title = đã cập nhậtTodo.Title todo.IsCompleted = đã cập nhậtTodo.IsCompleted; Results.NoContent(); }); app.MapDelete("/api/todos/{id}", (int id) => { var todo = todos.FirstOrDefault(t => t.Id == id); (todo == null) trả về Results.NotFound(); todos.Remove(todo); return Results.Ok() }); app.Run(); lớp công khai Todo { public int Id { get; } Tiêu đề chuỗi công khai { get;

API này cho phép bạn tạo, đọc, cập nhật và xóa các mục việc cần làm. Nó cho thấy cách xử lý các loại dữ liệu yêu cầu khác nhau và cách trả về phản hồi thích hợp.

Thông qua ví dụ này, bạn có thể thấy MiniAPI có thể dễ dàng xử lý các tác vụ xử lý dữ liệu khác nhau như thế nào. Cách tiếp cận ngắn gọn nhưng mạnh mẽ này giúp việc tạo các API giàu tính năng trở nên cực kỳ dễ dàng.

Hãy nhớ rằng, giống như việc thành thạo bất kỳ phép thuật nào, luyện tập là chìa khóa. Hãy thử mở rộng ví dụ này, thêm chức năng mới hoặc tạo API của riêng bạn. Khám phá và thử nghiệm là cách tốt nhất để trở thành bậc thầy về MiniAPI.

Trong chương tiếp theo, chúng ta sẽ đi sâu vào xử lý lỗi và quản lý ngoại lệ. Bạn đã sẵn sàng chưa? Hãy tiếp tục cuộc hành trình kỳ diệu của chúng tôi với MiniAPIs! .

7. Xử lý lỗi: thần chú bảo vệ của MiniAPIs

Chào mừng bạn đến với Chương 7 của Khóa học ma thuật MiniAPIs của chúng tôi! Hôm nay, chúng ta sẽ đi sâu vào xử lý lỗi trong MiniAPI. Hãy tưởng tượng nếu API của bạn là một lâu đài kiên cố thì việc xử lý lỗi là câu thần chú bảo vệ lâu đài, đảm bảo rằng API của bạn phản ứng một cách khéo léo ngay cả khi đối mặt với các tình huống không mong muốn. Hãy cùng học cách xây dựng những phép thuật bảo vệ mạnh mẽ này! .

Bắt và xử lý lỗi

Trong MiniAPI, có một số cách để xử lý lỗi và ngoại lệ. Hãy cùng khám phá từng cái một:

Sử dụng khối thử bắt

Cách cơ bản nhất để xử lý lỗi là sử dụng khối try-catch:

app.MapGet("/api/users/{id}", (int id) => { try { var user = GetUserById(id); // Giả sử rằng phương thức này có thể đưa ra một ngoại lệ return Results.Ok(user); } Catch (Exception ex) { return Results.Problem($"Đã xảy ra lỗi: {ex.Message}" } });

Cách tiếp cận này cho phép bạn nắm bắt và xử lý lỗi ở các điểm cuối cụ thể.

Sử dụng Results.Problem()

MiniAPI cung cấp phương thức Results.Problem(), phương thức này có thể được sử dụng để trả về các phản hồi lỗi được tiêu chuẩn hóa:

app.MapGet("/api/users/{id}", (int id) => { var user = GetUserById(id); if (user == null) return Results.Problem( statusCode: 404, title: "User không tìm thấy", chi tiết: $"Không tồn tại người dùng có ID {id}."); return Results.Ok(user); });

Results.Problem() sẽ tạo ra phản hồi IssueDetails phù hợp với đặc tả RFC7807.

Xử lý toàn cầu ngoại lệ

Để

app.Use(async (context, next) => { try { wait next(context); } Catch (Exception ex) { context.Response.StatusCode = 500; đang chờ context.Response.WriteAsJsonAsync(new { error = "One điều kiện không được mong đợi xảy ra lỗi." }); } });

Phần mềm trung gian này sẽ nắm bắt tất cả các ngoại lệ chưa được xử lý và trả về thông báo lỗi chung.

Tùy chỉnh lỗi phản hồi

Đôi khi, bạn có thể muốn trả lời tùy chỉnh phản hồi lỗi.

Tạo một tùy chỉnh lỗi đối tượng

Bạn có thể tạo tùy chỉnh lỗi đối tượng và trả lại khi cần:

lớp công khai ApiError { chuỗi công khai Tin nhắn { get; } chuỗi công khai [] Chi tiết { get; } } app.MapGet("/api/items/{id}", (int id) => { var item = GetItemById(id); if (item == null) trả về Results.NotFound(new ApiError { Message = "Item not Found", Details = new[] { $"Không có mục nào có ID {id} tồn tại." } }); ;

Sử dụng lớp problemDetails

Vấn đề cốt lõi của ASP.NETChi tiết mà bạn có thể sử dụng để tạo các phản hồi lỗi góp thủ RFC7807:

app.MapGet("/api/orders/{id}", (int id) => { var order = GetOrderById(id); if (order == null) return Results.Problem(new problemDetails { Status = 404, Title = "Không tìm thấy đơn hàng", Chi tiết = $"Không tồn tại tại đơn hàng nào có ID {id}.", Instance = $"/api/orders/{id}" }); Results.Ok(thứ tự);

Sử dụng phần mềm trung gian để xử lý lỗi

Middleware là một cách mạnh mẽ để xử lý lỗi tập trung. Trung gian để xử lý các loại ngoại lệ khác nhau:

app.Use(async (context, next) => { try { wait next(context); } Catch (Exception ex) { var problemDetails = new problemDetails(); switch (ex) { case NotFoundException notFound: problemDetails.Status = StatusCodes .Status404NotFound; problemDetails.Title = "Không tìm thấy tài liệu nguyên"; đứt gãy; đã xảy ra"; problemDetails.Detail = "Vui lòng liên hệ với bộ phận hỗ trợ nếu sự cố vẫn tồn tại."; } context.Response.StatusCode = problemDetails.Status.Value đang chờ context.Response.WriteAsJsonAsync(problemDetails);

Phần mềm trung gian này có thể xử lý các tùy chọn điều chỉnh ngoại lệ khác nhau và trả lời các lỗi phản hồi hợp lý.

Bài tập: Nâng cao khả năng xử lý lỗi của API cần thực hiện

Vui lòng quay lại API cần thực hiện của chúng tôi và nâng cao khả năng xử lý lỗi của nó:

var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); var todos = new List( ); cảnh.Response.StatusCode = 500 đang chờ; context.Response.WriteAsJsonAsync(new { error = "Đã xảy ra lỗi không mong muốn.", chi tiết = ex.Message } } }); việc cần làm", () => todos); MapGet("/api/todos/{id}", (int id) => { var todo = todos.FirstOrDefault(t => t.Id == id); if (todo == null) return Results.Problem( statusCode: 404, title: "Không tìm thấy công việc cần làm", chi tiết: $"Không tồn tại mục công việc cần làm có ID {id}."); Results.Ok(todo }); app.MapPost("/api/todos", (Todo todo) => { if (string.IsNullOrWhiteSpace(todo.Title)) trả về Results.BadRequest(new { error = "Yêu cầu tiêu đề." }); todo.Id = todos.Count + 1; $"/api/todos/{todo.Id}", todo }); ("/api/todos/{id}", (int id, TodoupdateTodo) => { var todo = todos.FirstOrDefault(t => t.Id == id); if (todo == null) trả về Results.NotFound(new { error = $"Không có mục nào cần làm có ID {id} tồn tại ." }); (string.IsNullOrWhiteSpace(updateTodo.Title)) trả về Results.BadRequest(new { error = "Yêu cầu tiêu đề." }); todo.Title =updateTodo.Title }); todos/{id}", (int id) => { var todo = todos.FirstOrDefault(t => t.Id == id); if (todo == null) return Results.NotFound(new { error = $"Không tồn tại mục công việc cần làm bất kỳ ID nào có ID {id}." }); todos.Remove(todo); trả về Results.Ok(); }); lớp công khai Todo { public int Id } Tiêu đề chuỗi công khai { được đặt } bool công khai IsCompleted { được đặt;

API nâng cấp này hiện bao gồm khả năng xử lý lỗi mạnh mẽ hơn:

  1. Chung tôi đã bổ sung thêm phần mềm chung xử lý lỗi trung gian để phát hiện các trường hợp ngoại lệ chưa được xử lý.
  2. Đối với trường hợp lý "Không tìm thấy", chúng tôi sử dụngKết quả.Problem()Trả về phản hồi lỗi đã được chuẩn hóa.
  3. Đối với các xác thực lỗi (chẳng hạn như tiêu đề trống), chúng tôi trả lời về Yêu cầu phản hồi không hợp lệ.
  4. Chúng tôi cung cấp thông báo xóa lỗi cho mọi tình huống có thể xảy ra.

Với những cải tiến này, API của chúng tôi hiện có thể xử lý các trạng thái lỗi khác nhau bằng một cách linh hoạt hơn, cung cấp thông tin thông báo xóa lỗi cho khách hàng.

Hãy nhớ rằng, việc xử lý lỗi tốt không chỉ cải thiện tính ổn định của API mà còn cải thiện đáng kể trải nghiệm API tốt phải có khả năng xử lý các tình huống lỗi khác nhau một cách khéo léo.

Trong chương tiếp theo, chúng tôi sẽ khám phá công việc xác thực và bảo mật dữ liệu. hành động bất kỳ của chúng tôi với MiniAPIs!

8. Thần chú hộ mệnh của MiniAPI

Chào mừng bạn đến với Chương 8 về Khóa học ma thuật MiniAPI của chúng tôi! Hôm nay chúng tôi sẽ tìm hiểu sâu về xác thực và bảo mật dữ liệu trong MiniAPI. dữ liệu là chú thích bảo vệ kho báu này, đảm bảo rằng chỉ những pháp luật mới được yêu cầu mới có thể truy cập và sửa đổi data value của bạn.

Dữ liệu xác thực phương thức

Trong MiniAPI, có một số cách để xác thực dữ liệu. Hãy cùng khám phá từng cái một:

1. Xác minh công cụ

Cách dễ dàng nhất là thực hiện xác thực theo cách thủ công trong quá trình xử lý:

app.MapPost("/api/users", (Người dùng người dùng) => { if (string.IsNullOrEmpty(user.Name)) return Results.BadRequest("Tên là bắt buộc."); if (user.Age < 0 | người dùng. Tuổi > 120) trở lại Results.BadRequest("Tuổi phải nằm trong khoảng từ 0 đến 120." // );

Phương pháp này đơn giản và dễ hiểu nhưng có thể dẫn đến mã hóa đối với logic xác thực phức tạp.

2. Sử dụng dữ liệu chú thích

Bạn có thể sử dụng chú thích dữ liệu trong lớp mô hình để xác định:

public class User { public int Id { get; set; } [Bắt buộc(ErrorMessage = "Tên là bắt buộc.")] [StringLength(100, MinimalLength = 2, ErrorMessage = "Tên phải từ 2 đến 100 ký tự." )] chuỗi công khai Tên { get; set; [Phạm vi (0, 120, ErrorMessage = "Tuổi phải nằm trong khoảng từ 0 đến 120.")] public int Tuổi { get; người dùng", (Người dùng người dùng) => { if (!ModelState.IsValid) return Results.ValidationProblem(ModelState); // ", user });

Cách tiếp cận này kết hợp xác thực logic hợp lý với mô hình định nghĩa, làm cho mã hóa rõ ràng hơn.

3. Sử dụng Xác thực thông tin

Xác thực thông thạo:

lớp công khai UserValidator : Tóm tắtValidator { public UserValidator() { RuleFor(x => x.Name).NotEmpty().Length(2, 100); RuleFor(x => x.Age).InclusiveBetween(0, 120 ); > x.Email).NotEmpty().EmailAddress(); Trong Program.cs builder.Services.AddValidatorsFromAssemblyContaining(); app.MapPost("/api/users", async (Người dùng người dùng, trình xác thực IValidator) => { var validationResult = chờ xác thực.ValidateAsync(user ) ; if (!validationResult.IsValid) trả về Results.ValidationProblem(validationResult.ToDictionary()); hợp lệ... return Results.Created($"/api/users/{user.Id}", user });

FluentValidation cung cấp một cách mạnh mẽ và linh hoạt để xác định quy tắc xác thực phức tạp.

Các phương pháp hay nhất để bảo mật API

API bảo mật của bạn là rất quan trọng. Dưới đây là một số phương pháp hay nhất:

1. Sử dụng HTTPS

Luôn sử dụng HTTPS để mã hóa dữ liệu khi truyền:

app.UseHttpsRedirection();

2. Thực hiện tỷ lệ giới hạn

API:

builder.Services.AddRateLimiter(options => { options.GlobalLimiter = Phân vùngRateLimiter.Create(httpContext => RateLimitPartition.GetFixedWindowLimiter(phân vùngKey: httpContext.User.Identity?.Name ?? httpContext.Request.Headers.Host. ToString(), nhà máy: phân vùng => mới FixedWindowRateLimiterOptions { AutoReplenishment = true, PermitLimit = 10 , QueueLimit = 0, Window = TimeSpan.FromMinutes(1) })); app.UseRateLimiter();

3.

Luôn luôn

app.MapPost("/api/comments", (CommentInput input) => { var cleanComment = System.Web.HttpUtility.HtmlEncode(input.Comment); // ;

4. Sử dụng hợp lệ HTTP code state

Sử dụng chính xác HTTP trạng thái mã hóa để chỉ ra các trạng thái lỗi khác nhau:

app.MapGet("/api/users/{id}", (int id) => { var user = GetUserById(id); if (user == null) return Results.NotFound(); if (!IsAuthorized(user) ) )) return Results.Forbid(); return Results.Ok(user });

Xác thực và ủy quyền

Lõi MiniAPI ASP.NET.

1. Xác thực thiết lập

Đầu tiên, bổ sung thêm dịch vụ xác thực:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) }; }); ứng dụng.UseAuthentication();

2. Bảo mật cuối cùng

Sau đó, bạn có thể sử dụng thuộc tính [Quyền] để bảo mật điểm cuối:

app.MapGet("/api/secure", [Authorize] (ClaimsPrincipal user) => { return $"Xin chào, {user.Identity.Name}!"; });

3. Phân quyền dựa trên vai trò

Bạn cũng có thể phát triển quyền khai thác dựa trên vai trò trò chơi:

app.MapGet("/api/admin", [Authorize(Roles = "Admin")] () => { return " Chào mừng, Quản trị viên!"; });

Bài tập thực hành: Tăng cường tính bảo mật của công việc API cần làm

Vui lòng quay lại API cần làm của chúng tôi và tăng cường tính bảo mật và xác thực dữ liệu của nó:

use System.Text; use Microsoft.AspNetCore.Authentication.JwtBearer; use Microsoft.IdentityModel.Tokens; use FluentValidation; var builder = WebApplication.CreateBuilder(args); tạo xác thực JWT.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key" ])) }; // Họ FluentValidation builder.Services.AddValidatorsFromAssemblyContaining(); ứng dụng var = builder.Build(); app.UseHttpsRedirection(); app.UseAuthentication();(); cảnh.Response.StatusCode = 500; đang chờ context.Response.WriteAsJsonAsync(new { error = "Đã xảy ra lỗi không mong muốn.", chi tiết = ex.Message } } }); app.MapGet("/api/todos/{id}", [Ủy quyền] (int id) => { var todo = todos.FirstOrDefault(t => t.Id == id); if (todo == null ) return Results.NotFound(new { error = $"Không có mục việc nào cần làm có ID {id} tồn tại." }); .Ok(todo); }); app.MapPost("/api/todos", [Ủy quyền] không đồng bộ ( Trình xác thực Todo todo, IValidator) => { var validationResult = chờ xác thực.ValidateAsync(todo); if (!validationResult.IsValid) trả về Results.ValidationProblem(validationResult.ToDictionary()); Results.Created($"/api/todos/{todo.Id}", todo }); app.MapPut("/api/todos/{id}", [Ủy quyền] async (int id, TodoupdateTodo, Trình xác thực trình xác thực IValidator) => { var todo = todos.FirstOrDefault(t => t.Id == id); (todo == null) return Results.NotFound(new { error = $"Không có mục nào cần làm có ID {id); } tồn tại." }); var validationResult = chờ xác thực.ValidateAsync(updateTodo); Results.ValidationProblem(validationResult.ToDictionary()); api/todos/{id}", [Authorize] (int id) => { var todo = todos.FirstOrDefault( t => t.Id == id); if (todo == null) trả về Kết quả.NotFound(new { error = $"Không có công việc cần làm có ID {id} tồn tại." }); todos.Remove(todo); return Results.Ok() }); ; } chuỗi công khai Tiêu đề { get; set; } public bool IsCompleted { set; } } lớp công khai TodoValidator : Tóm tắt tắt Trình xác thực { public TodoValidator() { RuleFor(x => x.Tiêu đề).NotEmpty().MaximumLength(100);

API nâng cấp này hiện bao gồm các tính năng xác thực dữ liệu và bảo mật mạnh mẽ hơn:

  1. Chúng tôi đã xác thực JWT và tất cả các điểm cuối cùng đều yêu cầu xác thực để truy cập.
  2. Chúng tôi sử dụng FluentValidation để xác thực mục tiêu đảm bảo rằng mục tiêu của Todo trống và không vượt quá quá 100 ký tự.
  3. Chúng tôi sử dụng HTTPS chuyển hướng để đảm bảo tất cả thông tin liên lạc đều được mã hóa.
  4. Chúng tôi duy trì toàn bộ phần mềm xử lý lỗi trung gian để xử lý các trường hợp ngoại lệ không mong muốn.

Với những cải tiến này, API của chúng tôi hiện an toàn hơn và có khả năng chống lại các cuộc tấn công tiềm ẩn cũng như dữ liệu dữ liệu không hợp lệ. khai triển nhiều biện pháp bảo mật hơn.

Trong chương tiếp theo, chúng tôi sẽ khám phá cách kết hợp MiniAPI với cơ sở dữ liệu. hành động bất kỳ của chúng tôi với MiniAPIs!

9. API nhỏ

Chào mừng bạn đến với Chương 9 Khóa học ma thuật MiniAPIs của chúng tôi! tương tác với cơ sở dữ liệu. chính là ma thuật giá sách của thư viện này, lưu trữ tất cả thông tin quý giá. Những giá sách kỳ diệu này nhé!

Kết nối với cơ sở dữ liệu

Trong MiniAPI, chúng tôi thường sử dụng Entity Framework Core (EF Core) để tương tác với cơ sở dữ liệu. object)mạnh mẽ cho phép chúng tôi sử dụng mã C# để vận hành cơ sở dữ liệu.

Đầu tiên, chúng tôi cần cài đặt các gói NuGet cần thiết:

gói bổ sung dotnet Microsoft.EntityFrameworkCore.SqlServer gói bổ sung dotnet Microsoft.EntityFrameworkCore.Design

Sau đó, chúng tôi cần tạo một cơ sở dữ liệu lớp bối cảnh:

use Microsoft.EntityFrameworkCore; lớp công khai TodoDbContext : DbContext { public TodoDbContext(DbContextOptions tùy chọn): cơ sở (tùy chọn) { } DbSet công khai Việc cần làm { bộ;

Chương trình.cs:

var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

Đảm bảo bổ sung thêm kết nối chuỗi vào tệp appsinstall.json của bạn:

{ "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=TodoDb;Trusted_Connection=True;"

Thực hiện các thao tác cơ bản CRUD

Bây giờ chúng tôi đã kết nối với cơ sở dữ liệu, hãy xem cách thực hiện các thao tác CRUD (Tạo, Đọc, Cập nhật, Xóa) cơ sở dữ liệu version.

Create.,..

app.MapPost("/api/todos", async (Todo todo, TodoDbContext db) => { db.Todos.Add(todo); chờ db.SaveChangesAsync(); return Results.Created($"/api/todos/ {todo.Id}", việc cần làm); });

Đọc

app.MapGet("/api/todos", async (TodoDbContext db) => đang chờ db.Todos.ToListAsync()); app.MapGet("/api/todos/{id}", async (int id, TodoDbContext) db ) => { var todo = đang chờ db.Todos.FindAsync(id); là null ? Results.NotFound() : Results.Ok(todo });

Update

app.MapPut("/api/todos/{id}", async (int id, Todo inputTodo, TodoDbContext db) => { var todo = wait db.Todos.FindAsync(id); if (todo is null) trả về Kết quả .NotFound(); todo.IsCompleted = inputTodo.IsCompleted; đang chờ db.SaveChangesAsync(); trả về Results.NoContent();

Remove

app.MapDelete("/api/todos/{id}", async (int id, TodoDbContext db) => { var todo = chờ db.Todos.FindAsync(id); if (todo là null) trả về Results.NotFound ( ); db.Todos.Remove(todo); chờ trả về db.SaveChangesAsync(); Kết quả.Ok();

Use tool ORM (Ánh xạ quan hệ đối tượng)

Chúng tôi đã sử dụng Entity Framework Core trong ví dụ trên, đây là công cụ ORM phổ biến nhất trong hệ sinh thái .NET. Có nhiều lợi ích khi sử dụng. sử dụng ORM:

  1. an toàn loại: ORM cho phép chúng tôi sử dụng C# đối tượng được nhập mạnh mẽ thay vì xử lý trực tiếp các chuỗi SQL.
  2. Đối tượng cơ sở dữ liệu hoạt động: ORM
  3. Cơ sở dữ liệu cài đặt độc lập: Bằng cách thay đổi cấu hình, chúng tôi có thể dễ dàng chuyển sang cơ sở dữ liệu hệ thống khác.
  4. Hiệu suất tối ưu: Nhiều công cụ ORM (bao gồm cả EF Core) được tích hợp sẵn các tính năng tối ưu hóa hiệu suất.

Tuy nhiên, có một số lưu ý khi sử dụng ORM:

  1. đường cong học tập: Khó hiểu và sử dụng ORM một cách hiệu quả có thể bị mất trong một thời gian.
  2. Performance Performance: Trong một số phức tạp truy vấn, ORM có thể không hiệu quả bằng cách truy vấn SQL trực tiếp.
  3. Blackbox active: Đôi khi rất khó để hiểu ORM đang thực hiện SQL gì.

Bài tập thực hành: Tích hợp API cần làm với cơ sở dữ liệu

Vui lòng tích hợp các API hợp lý mà chúng tôi cần làm với cơ sở dữ liệu SQL Server.

Sau đó, cập nhật tệp Program.cs của bạn:

use Microsoft.EntityFrameworkCore; use System.ComponentModel.DataAnnotations; use FluentValidation; var builder = WebApplication.CreateBuilder(args); dữ liệu.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString("Kết nối mặc định"))); Thêm FluentValidation builder.Services.AddValidatorsFromAssemblyContaining(); var app = builder.Build(); // Ngoại lệ cũ) { bối cảnh.Response.StatusCode = 500; đang chờ context.Response.WriteAsJsonAsync(new { error = "Đã xảy ra lỗi không mong muốn.", chi tiết = ex.Message } } }); db.Todos.ToListAsync()); app.MapGet("/api/todos/{id}", async (int id, TodoDbContext db) => { var todo = chờ db.Todos.FindAsync(id); return todo là null ? Results.NotFound(new { error = $"No item công việc cần làm có ID {id} tồn tại." }): Results.Ok(todo }); app.MapPost("/api/todos", async (Todo todo, TodoDbContext db, IValidator validator) => { var validationResult = chờ validator.ValidateAsync(todo); if (!validationResult.IsValid) trả về Results.ValidationProblem (xác thựcResult.ToDictionary()); db.SaveChangesAsync(); return Results.Created($"/api/todos/{todo.Id}", todo }); /{id}", không đồng bộ (int id, Todo inputTodo, TodoDbContext db, IValidator validator) => { var todo = wait db.Todos.FindAsync(id); if (todo is null) return Results.NotFound(new { error = $"Không tồn tại mục công việc cần làm bất kỳ ID nào có ID {id}." var validationResult = đang chờ trình duyệt xác thực.ValidateAsync(inputTodo); if (!validationResult.IsValid) trả về Results.ValidationProblem(validationResult.ToDictionary()); db.SaveChangesAsync(); api/todos/{id}", không đồng bộ (int id, TodoDbContext db) => { var todo = wait db.Todos.FindAsync(id); if (todo is null) return Results. NotFound(new { error = $"Không tồn tại lớp công khai Todo { public int Id { get; set; } [Bắt buộc] Tiêu đề chuỗi công khai { get; } bool công khai IsCompleted { get; public TodoValidator() { RuleFor(x => x.Title).NotEmpty().MaximumLength(100) ; } khai báo lớp TodoDbContext : DbContext { public TodoDbContext(DbContextOptions tùy chọn): cơ sở (tùy chọn) { } DbSet công khai Việc cần làm { bộ;

Phiên bản API này đã hợp lý hóa đầy đủ cơ sở dữ liệu hoạt động:

  1. Entity Framework Core Entity Framework Core SQL Server.
  2. Tất cả CRUD hoạt động đều được liên tục và dữ liệu được lưu trữ trong cơ sở dữ liệu.
  3. Chúng tôi đã giữ lại quá trình xử lý lỗi logic và xác thực dữ liệu trước đó.
  4. Chúng tôi sử dụng các phương pháp không đồng bộ cho tất cả hoạt động của cơ sở dữ liệu, giúp cải thiện hiệu quả hiệu quả và khả năng mở rộng của ứng dụng.

You can can thực hiện công việc này bằng EF Core command sau:

di chuyển dotnet ef add ban Tạo cập nhật cơ sở dữ liệu dotnet ef

Với những cải tiến này, API của chúng tôi hiện tại không chỉ có thể xử lý các HTTP yêu cầu mà còn có thể lưu trữ dữ liệu vào cơ sở dữ liệu.

Trong chương trình tiếp theo, chúng tôi sẽ khám phá một số tính năng nâng cao của MiniAPI. chúng tôi sử dụng quy trình này với MiniAPIs!

10. Các tính năng nâng cao: Sự tiến bộ kỳ diệu của MiniAPI

Chào mừng bạn đến với Chương 10 Khóa học ma thuật MiniAPIs của chúng tôi ngày nay, chúng tôi sẽ khám phá một số tính năng nâng cao cao của MiniAPI. cao này là chìa khóa giúp bạn trở thành bậc thầy phép thuật thực sự. mạnh mẽ nhé!

Việc sử dụng và viết phần mềm trung gian

Middleware là thành phần phần mềm trong ứng dụng ASP.NET Core đường dẫn sử dụng phần mềm trung gian hiện có hoặc tạo phần mềm tùy chỉnh trung gian.

Sử dụng phần mềm trung gian tích hợp

ASP.NET Core có sẵn mà chúng ta có thể sử dụng trong MiniAPI:

var app = builder.Build(); app.UseHttpsRedirection(); app.UseStaticFiles();

Tạo phần mềm trung gian tùy chỉnh

Chúng tôi cũng có thể tạo các phần mềm tùy chỉnh trung gian để đáp ứng các công cụ nhu cầu:

lớp công khaiRequestLoggingMiddleware { riêng tư chỉ đọcRequestDelegate _next; riêng tư đọc ILogger _logger publicRequestLoggingMiddleware(RequestDelegate next, ILogger; logger) { _next = next; _logger = logger; _logger.LogInformation($"Đã nhận được yêu cầu: {context.Request.Method} {context.Request.Path}"); ; } } // Sử dụng ứng dụng app.UseMiddleware();

Tải lên và tải xuống tập tin

MiniAPI có thể dễ dàng xử lý các hoạt động tải lên và tải xuống tệp.

Tải tập tin lên

app.MapPost("/upload", async (tệp IFormFile) => { if (file.Length > 0) { var path = Path.Combine(Directory.GetCurrentDirectory(), "uploads", file.FileName); sử dụng var luồng = New FileStream (đường dẫn, FileMode.Create); đang chờ tệp.CopyToAsync (luồng trả về Results.Ok (mới {) file.FileName, file.Length } } return Results.BadRequest("Không có tệp nào được nhận" tải lên." });

Tải file xuống

app.MapGet("/download/{fileName}", (string fileName) => { var path = Path.Combine(Directory.GetCurrentDirectory(), "uploads", fileName); if (!System.IO.File.Exists (đường dẫn)) return Results.NotFound($"Không tìm thấy tệp {fileName}."); return Results.File(path, "application/octet-stream", fileName); });

Triển khai kiểm tra API phiên bản

Trọng MiniAPI, chúng tôi có thể sử dụng gói Asp.Versioning.Http để phát triển bảng kiểm soát phiên bản.

Đầu tiên, cài đặt các gói NuGet cần thiết:

dotnet add gói Asp.Versioning.Http

Sau đó, cấu hình API phiên bản trong Program.cs của bạn:

var builder = WebApplication.CreateBuilder(args); builder.Services.AddApiVersioning(options => { options.DefaultApiVersion = new ApiVersion(1, 0); options.AssumeDefaultVersionWhenUnspecified = true; options.ReportApiVersions = true; }); (); app.MapGet("/api/v{version:apiVersion}/hello", (ApiVersion version) => $"Xin chào từ phiên bản API {version}!") .WithApiVersionSet(versionSet) .MapToApiVersion(1.0); "/api/v{version:apiVersion}/hello", (phiên bản ApiVersion) => $"Lời chào từ API phiên bản {version}!") .WithApiVersionSet(versionSet) .MapToApiVersion(2.0);app.Run();

Ví dụ này đã tìm ra cách tạo các phiên bản khác nhau của cùng một tuyến đường.

Quản lý vòng nhập và phụ thuộc

Hỗ trợ đầy đủ hệ thống phụ thuộc (DI) phụ trợ (DI) của ASP.NET Core. phần phụ thuộc của dịch vụ.

Đăng ký dịch vụ

Trong Program.cs bạn có thể đăng ký dịch vụ:

var builder = WebApplication.CreateBuilder(args); builder.Services.AddSingleton(); người xây dựng.Services.AddScoped(); builder.Services.AddTransient(); ứng dụng = builder.Build();

Use use service

Trong quá trình xử lý điểm cuối, bạn có thể sử dụng trực tiếp các dịch vụ này:

app.MapGet("/api/data", (IMyService myService, IMyDbContext dbContext) => { var data = myService.GetData(); dbContext.SaveData(data); return Results.Ok(data); });

Lập trình không đồng bộ

API nhỏ mở rộng ứng dụng.

app.MapGet("/api/data", async (IMyAsyncService myService) => { var data = chờ myService.GetDataAsync(); return Results.Ok(data); });

Bài tập thực hành: API cần nâng cao

Vui lòng áp dụng các tính năng nâng cao này cho API mà chúng tôi cần làm:

sử dụng Microsoft.EntityFrameworkCore; sử dụng System.ComponentModel.DataAnnotations; sử dụng FluentValidation; sử dụng Microsoft.AspNetCore.Mvc; var builder = WebApplication.CreateBuilder(args); tạo bối cảnh cơ sở dữ liệu.Services.AddDbContext(options =>) options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); // Thêm FluentValidation builder.Services.AddValidatorsFromAssemblyContaining(); // Thêm API kiểm soát phiên bản builder.Services.AddApiVersioning(options => { options. DefaultApiVersion = ApiVersion new (1, 0); options.AssumeDefaultVersionWhenUnspecified = true; options.ReportApiVersions = true; }); = người xây dựng.Build(); Phần mềm trung gian tùy chỉnh: Yêu cầu ghi nhật ký app.Use(async (context , next) => { var start = DateTime.UtcNow; đang chờ tiếp theo(); var end = DateTime.UtcNow; var thời gian = kết thúc - bắt đầu; Console.WriteLine($"Yêu cầu {context.Request.Path} mất {duration.TotalMilliseconds}ms" }); // API v1 var v1 = app.NewApiVersion(1, 0); app.MapGet("/api/v{version:apiVersion}/todos", async (TodoDbContext db) => đang chờ db.Todos.ToListAsync()) .WithApiVersionSet(v1); {version:apiVersion}/todos/{id}", không đồng bộ (int id, TodoDbContext db) => { var todo = đang chờ db.Todos.FindAsync(id); trả về công việc cần làm là null? { error = $"Không tồn tại tại mục công việc cần làm có ID nào {id}." }) : Results.Ok(todo); }) .WithApiVersionSet(v1); ", không đồng bộ (Todo todo, TodoDbContext db, xác thực IValidator) => { var validationResult = đang chờ validator.ValidateAsync(todo); if (!validationResult.IsValid) trả về Results.ValidationProblem(validationResult.ToDictionary()); db.SaveChangesAsync(); api/todos/{todo.Id}", việc cần làm); }) .WithApiVersionSet(v1); app.MapPut("/api/v{version:apiVersion}/todos/{id} ", không đồng bộ (int id, Todo inputTodo, TodoDbContext db, trình xác thực IValidator) => { var todo = chờ db.Todos.FindAsync(id); nếu (việc cần làm là null) trả về Results.NotFound(new { error = $"Không có mục việc cần làm nào có ID {id} tồn tại." }); var validationResult = đang chờ validator.ValidateAsync(inputTodo); ()); todo.Title = inputTodo.Title; todo.IsCompleted = inputTodo.IsCompleted; đang chờ db.SaveChangesAsync(); trả về Results.NoContent(); }) .WithApiVersionSet(v1); int id, TodoDbContext db) => { var todo = đang chờ db.Todos.FindAsync(id); if (todo is null) return Results.NotFound(new { error = $"Không có mục việc cần làm nào có ID {id} tồn tại." }); db.SaveChangesAsync(); trả về Results.Ok() }) .WithApiVersionSet(v1); Tải lên và tải xuống tệp app.MapPost("/api/v{version:apiVersion}/upload", async (tệp IFormFile) => { if (file.Độ dài > 0) { var path = Path.Combine(Directory.GetCurrentDirectory(), "uploads", file.FileName); sử dụng varstream = new FileStream(path, FileMode.Create); đang chờ file.CopyToAsync(stream); Results.Ok(new { file.FileName, file.Length }); } return Results.BadRequest("Không có tập tin đã tải lên."); }) .WithApiVersionSet(v1); app.MapGet("/api/v{version:apiVersion}/download/{fileName}", (string fileName) => { var path = Path.Combine(Directory .GetCurrentDirectory(), "tải lên", fileName); if (!System.IO.File.Exists(path)) trả về Results.NotFound($"Không tìm thấy tệp {fileName}."); return Results.File(path, "application/octet-stream", fileName }) .WithApiVersionSet(v1); Todo { public int Id { get; set; } [Bắt buộc] Tiêu đề chuỗi công khai { get; } public bool IsCompleted { get; TodoValidator : Tóm tắtValidator { public TodoValidator() { RuleFor(x => x.Title).NotEmpty().MaximumLength(100); } } public class TodoDbContext : DbContext { public TodoDbContext(DbContextOptions options): base (tùy chọn) { } công khai DbSet Todos { được; đặt;

Phiên bản nâng cao này của API hiện bao gồm các tính năng sau:

  1. Phiên bản API: Tất cả các điểm cuối đều được phiên bản.
  2. Middleware tùy chỉnh: dùng để ghi lại thời gian xử lý yêu cầu.
  3. Chức năng tải lên và tải xuống tập tin.
  4. Xác thực dữ liệu trước đó, xử lý lỗi và hoạt động cơ sở dữ liệu được giữ lại.

Với những tính năng nâng cao này, API của chúng tôi trở nên mạnh mẽ và linh hoạt hơn. Giờ đây nó có thể xử lý việc kiểm soát phiên bản, thao tác tệp và cung cấp khả năng giám sát hiệu suất tốt hơn.

Hãy nhớ rằng, việc thành thạo các tính năng nâng cao này cần có thời gian và luyện tập. Đừng ngại thử nghiệm và thử những điều mới. Mỗi lần thử sẽ đưa bạn đến gần hơn với việc trở thành bậc thầy ma thuật MiniAPIs thực sự! .

Trong chương tiếp theo, chúng ta sẽ khám phá cách kiểm tra và gỡ lỗi ứng dụng MiniAPI của bạn. Bạn đã sẵn sàng chưa? Hãy tiếp tục cuộc hành trình kỳ diệu của chúng tôi với MiniAPIs! .

11. Kiểm tra và gỡ lỗi: Sự phát hiện kỳ diệu của MiniAPI

Chào mừng bạn đến với Chương 11 về Khóa học ma thuật MiniAPIs của chúng tôi ngày nay, chúng tôi sẽ đi sâu vào cách kiểm tra và gỡ bỏ ứng dụng MiniAPI của bạn bị lỗi. một nhà phát triển giỏi cần kiểm tra và gỡ lỗi mã của mình một cách cẩn thận. kỹ thuật phát hiện sức mạnh mạnh mẽ này .

Viết bài kiểm tra đơn vị

API nhỏ, chúng tôi có thể sử dụng các kiểm tra khung như xUnit, NUnit hoặc MSTest để viết bài kiểm tra đơn vị.

Bản dịch:

dotnet xunit new -n TodoApi.Tests dotnet more TodoApi.Tests tham khảo TodoApi

Bây giờ, hãy viết một số bài kiểm tra đơn vị cho TodoService của chúng ta:

use Xunit; use Moq; use TodoApi.Services; [Thực tế] công khai không đồng bộ Nhiệm vụ GetAllTodos_ReturnsAllTodos() { // Sắp xếp var mockSet = new Mock>(); var mockContext = Mô hình mới(); mockContext.Setup(m => m.Todos).Returns(mockSet.Object); var service = new TodoService(mockContext.Object); // Hành động var result = chờ dịch vụ.GetAllTodosAsync(); Định nghĩa chính xác Assert.NotNull(result); mockSet.Verify(m => m.ToListAsync(It.IsAny()), Times.Once()); } [Fact] public async Task CreateTodo_AddsTodoToDatabase() { // Sắp xếp var mockSet = new Mock<>>(); mockContext = Mô phỏng mới(); mockContext.Setup(m => m.Todos).Returns(mockSet.Object); var service = new TodoService(mockContext.Object); var todo = new Todo { Title = "Test Todo" } // Hành động đang chờ dịch vụ.CreateTodoAsync(todo); Khẳng định mockSet.Verify(m => m.AddAsync(It.IsAny(), It.IsAny()), Times.Once()); mockContext.Verify(m => m.SaveChangesAsync(It.IsAny()), Times.Once());

Những thử nghiệm này đảm bảo rằng TodoService của chúng tôi tương thích với cơ sở dữ liệu một cách chính xác.

Viết bài kiểm tra hợp lý

API nhỏ, chúng tôi có thể sử dụng WebApplicationFactory để tạo thử nghiệm máy chủ.

use Microsoft.AspNetCore.Mvc.Testing; use System.Net.Http.Json; use Xunit; không có tên TodoApi.Tests { lớp khai báo TodoApiIntegrationTests : IClassFixture<>> { dành riêng đọc chỉ WebApplicationFactory _factory; TodoApiIntegrationTests(WebApplicationFactory Factory) { _factory = Factory; } [Fact] public async Task GetTodos_ReturnsSuccessStatusCode() { // Sắp xếp var client = _factory.CreateClient(); // Act var reply = wait client.GetAsync("/api /v1/todos" ); // K xác định reply.EnsureSuccessStatusCode(); } [Thực tế] công khai không đồng bộ nhiệm vụ CreateTodo_ReturnsCreatedStatusCode() { // Sắp xếp var client = _factory.CreateClient(); "Todo Test hợp nhất" }; đang chờ client.PostAsJsonAsync("/api/v1/todos", todo); // K kiềm định Assert.Equal(System.Net.HttpStatusCode.Created, reply.StatusCode);

Những thử nghiệm này đảm bảo rằng API cuối cùng của chúng tôi đã phản hồi chính xác các yêu cầu.

Use debug tool

.NET cung cấp các công cụ mạnh mẽ để giúp bạn mong đợi và giải quyết sự cố.

Use point stop

Mã Visual Studio, bạn có thể đặt điểm dừng bằng cách nhấp vào bên trái số dòng. đến điểm ngắt, nó sẽ tạm dừng, cho phép bạn kiểm tra giá trị của các biến và trạng thái của chương trình.

Sử dụng ký tự Nhật Bản

Mini API, bạn có thể sử dụng hợp đồng ghi nhật ký hệ thống:

app.MapGet("/api/v1/todos", async (ILogger logger, TodoDbContext db) => { logger.LogInformation("Nhận tất cả công việc cần làm"); var todos = chờ db.Todos.ToListAsync(); logger.LogInformation($"Đã truy xuất {todos.Count} todos"); Results.Ok(todos);

Bạn có thể sử dụng các nhật ký cấp độ khác nhau (chẳng hạn như LogDebug, LogWarning, LogError, vv) để phân biệt các thông tin có tầm quan trọng khác nhau.

Sử dụng ngoại lệ xử lý

Quá trình xử lý ngoại lệ thích hợp có thể giúp bạn vượt qua vấn đề một cách dễ dàng hơn:

app.MapPost("/api/v1/todos", async (Todo todo, TodoDbContext db) => { try { db.Todos.Add(todo); đang chờ db.SaveChangesAsync(); return Results.Created($" /api/v1/todos/{todo.Id}", todo); } Catch (Ngoại lệ cũ) { logger.LogError(ex, "Đã xảy ra lỗi khi tạo một công việc cần làm mới"); return Results.Problem("Đã xảy ra lỗi khi xử lý yêu cầu của bạn.");

Hiệu suất tối ưu hóa

Hiệu suất tối ưu là một khía cạnh quan trọng của quá trình phát triển. Hiệu suất ưu tiên của MiniAPI:

  1. Sử dụng trình cài đặt không đồng bộ: Sử dụng các phương pháp không đồng bộ bất cứ khi nào có thể, đặc biệt là trong các phương pháp I/O hoạt động.

  2. Cơ sở dữ liệu truy vấn được ưu tiên tối ưu: sử dụng các mục phù hợp để tránh các vấn đề về truy vấn N+1.

  3. Triển khai bộ đệm: Đối với dữ liệu được truy cập thường xuyên nhưng ít thay đổi, cân nhắc sử dụng bộ đệm đệm.

  4. Sử dụng tính năng nén: Việc bật tính năng nén phản hồi có thể làm giảm lượng dữ liệu được truyền tải.

  5. Giảm thiểu việc sử dụng các tính năng chèn phụ thuộc: Mặc dù tính năng chèn phụ thuộc rất hữu ích nhưng việc sử dụng ứng dụng có thể ảnh hưởng đến hiệu suất.

  6. Sử dụng cấu trúc phù hợp với dữ liệu: Việc chọn cấu trúc phù hợp với dữ liệu có thể cải thiện đáng kể hiệu suất.

Bài tập thực hành: Công việc API tối ưu hóa và kiểm tra cần làm

Vui lòng thực hiện một số công việc API tối ưu hóa mà chúng tôi cần thực hiện và bổ sung một số thử nghiệm:

  1. Đầu tiên, ưu tiên hóaViệc cần làm dịch vụ:
lớp công khai TodoService : ITodoService { riêng tư đọc TodoDbContext _context riêng tư đọc IMemoryCache _cache riêng tư đọc ILogger; _logger; TodoService công khai (ngữ cảnh TodoDbContext, bộ đệm IMemoryCache, ILogger logger) { _context = context; logger; không đồng bộ khai báo Task<>> GetAllTodosAsync() { return wait _cache.GetOrCreateAsync("all_todos", async entry => { entry.SetAbsoluteExpiration(TimeSpan.FromMinutes(5)); _logger.LogInformation("Đang tìm tất cả công việc cần làm from cơ sở dữ liệu") ; trả về đang chờ _context.Todos.ToListAsync(); }); } task không đồng bộ công khai GetTodoByIdAsync(int id) { return đang chờ _cache.GetOrCreateAsync($"todo_{id}", mục nhập không đồng bộ => { entry.SetAbsoluteExpiration(TimeSpan.FromMinutes(5)); _logger.LogInformation ($"Đang tìm tải công việc cần làm với id {id} từ cơ sở dữ liệu"); _context.Todos.FindAsync(id); }); } Nhiệm vụ không đồng bộ công khai CreateTodoAsync(Todo todo) { _context.Todos.Add(todo); đang chờ _context.SaveChangesAsync(); _logger.LogInformation($"Đã tạo công việc mới với id {todo.Id}"); / Triển khai các phương thức khác... }
  1. Sau đó, hãy thêm một số đơn vị bài kiểm tra cho dịch vụ này:
public class TodoServiceTests { [Fact] public async Task GetAllTodos_ReturnsCachedResult() { // Sắp xếp var mockContext = new Mock(); var mockCache = Mock mới(); var cachedTodos = Danh sách mới { Việc cần làm mới { Id = 1, Title = "Todo được lưu trong bộ nhớ đệm" } }; mockCache.Setup(c => c.TryGetValue("all_todos", out It.Ref.IsAny)) .Returns(true) .Callback(new OutDelegate ((khóa chuỗi, object value out) => value = cachedTodos)); var service = new TodoService(mockContext.Object, mockCache.Object, mockLogger.Object // Act var result = wait service.GetAllTodosAsync()); ; // Khẳng định Assert.Equal(cachedTodos, result); , Times.Never); } [Thực tế] Nhiệm vụ không đồng bộ công khai CreateTodo_InvalidatesCacheAndSavesToDatabase() { // Sắp xếp var mockContext = new Mock(); var mockCache = Mock mới(); var mockLogger = Mock mới<>>(); , mockLogger.Object); var todo = new Todo { Title = "New Todo" }; service.CreateTodoAsync(todo); // Khẳng định mockCache.Verify(c => c.Remove("all_todos") , Times.Once mockContext.Verify(c => c.SaveChangesAsync(It.IsAny()); ), Lần.Một lần);
  1. Cuối cùng, vui lòng thêm một bài kiểm tra kiểm tra:
lớp công khai TodoApiIntegrationTests : IClassFixture<>> { dành riêng đọc chỉ WebApplicationFactory _factory; TodoApiIntegrationTests công khai(WebApplicationFactory Factory) { _factory = Factory } [Fact] không đồng bộ công khai Task CreateAndGetTodo_ReturnsCreatedTodo() { // Sắp xếp var client = _factory.CreateClient(); var todo = new Todo { Title = "Todo kiểm tra tích hợp" } / / Hành động var createResponse = chờ đợi client.PostAsJsonAsync("/api/v1/todos", createResponse.EnsureSuccessStatusCode ();(); var getResponse = chờ client.GetAsync($"/api/v1/todos/{createdTodo.Id}");(); // K khẳng định Assert.NotNull(createdTodo); Assert.NotNull(retrievedTodo);

Thông qua những tối ưu hóa và thử nghiệm này, API của chúng tôi ở đây mạnh mẽ và hiệu quả hơn:

  1. Chúng tôi sử dụng bộ nhớ đệm để giảm bớt việc truy cập cơ sở dữ liệu.
  2. Chúng tôi đã bổ sung thêm tính năng ghi nhật ký chi tiết để giúp gỡ lỗi.
  3. Chúng tôi đã viết các bài kiểm tra đơn vị để đảm bảo rằng các dịch vụ logic của chúng tôi là chính xác.
  4. Chúng tôi đã bổ sung các thử nghiệm hợp lý để xác định rằng API cuối cùng của chúng tôi hoạt động như mong đợi.

Hãy nhớ rằng, kiểm tra và gỡ lỗi là một quá trình liên tục. mới và sử dụng công cụ gỡ lỗi để dự đoán và giải quyết sự cố.

Trong chương trình tiếp theo, chúng tôi sẽ khám phá cách phát triển ứng dụng MiniAPI của bạn. chúng tôi sử dụng quy trình này với MiniAPIs!

12. Triển khai ứng dụng MiniAPIs: mang lại điều kỳ diệu cho thế giới thực thi

Chào mừng bạn đến với Chương 12 Khóa học ma thuật MiniAPI của chúng tôi ngày nay, chúng tôi sẽ tìm hiểu cách phát triển ứng dụng API nhỏ được bạn thiết kế cẩn thận trong thế giới thực tế. Giống như kỹ thuật ảo cần thiết cho kỹ thuật ảo. Hãy cùng nhau tìm hiểu cách MiniAPI được phép của bạn để nâng cấp một tầm cao mới!

Triển khai tới local server

Trước tiên, hãy xem cách phát triển ứng dụng MiniAPIs lên máy chủ cục bộ.

Bước 1: Xuất bản ứng dụng

Trong dự án thư mục của bạn, hãy chạy lệnh sau:

xuất bản dotnet -c Phát hành -o ./publish

Thao tác này sẽ tạo một thư mục xuất hiện chứa ứng dụng của bạn và tất cả các phần phụ thuộc của nó.

Bước 2: Cấu hình IIS

  1. Cài đặt IIS trên máy chủ Windows.
  2. Cài đặt gói lưu trữ .NET Core.
  3. Tạo một trang web mới trong IIS và đường dẫn con trỏ của nó tới trang web của bạn xuất bản folder.

Bước 3: Định cấu hình ứng dụng nhóm

  1. Tạo nhóm ứng dụng mới cho ứng dụng của bạn.
  2. Đặt ứng dụng nhóm thành "Không quản lý được mã hóa".

Bước 4: Cấu hình web.config

Tạo tệp web.config trong bản xuất thư mục của bạn:

          

Đảm bảo thay thế YourAppName.dll bằng tên DLL thực tế của ứng dụng của bạn.

Triển khai nền tảng đám mây

Bây giờ, hãy xem cách phát triển các ứng dụng MiniAPIs trên nền tảng đám mây phổ biến.

Triển khai ứng dụng dịch vụ Azure

  1. Trong Visual Studio, nhấp chuột phải vào dự án của bạn và chọn "Xuất bản".
  2. Chọn "Azure" làm tiêu điểm.
  3. Chọn "Dịch vụ ứng dụng Azure (Windows)".
  4. Tạo Dịch vụ ứng dụng mới hoặc chọn một dịch vụ hiện có.
  5. Nhấp vào "Xuất bản".

Ngoài ra, bạn có thể sử dụng Azure CLI:

az webapp up --sku F1 --name  --os-type windows

Triển khai lên AWS Elastic Beanstalk

  1. Cài đặt Bộ công cụ AWS cho Visual Studio.
  2. Nhấp chuột phải vào dự án của bạn và chọn "Xuất bản lên AWS".
  3. Chọn "Cây đậu đàn hồi AWS".
  4. Tạo môi trường mới hoặc chọn môi trường hiện có.
  5. Nhấp vào "Xuất bản".

Triển khai tới Heroku

  1. Tạo một Procfile trong thư mục gốc dự án của bạn:

    web: cd $HOME/heroku_output && dotnet YourAppName.dll --urls=http://+:$PORT
    
  2. Cài đặt Heroku CLI và đăng nhập.

  3. Tạo một ứng dụng Heroku mới:

    heroku tạo tên ứng dụng của bạn
    
  4. Thiết lập gói xây dựng:

    gói xây dựng heroku: set jincod/dotnetcore
    
  5. Triển khai ứng dụng của bạn:

    git đẩy heroku chính
    

Tích hợp liên tục và phát triển khai liên tục (CI/CD)

Việc thiết lập quy trình CI/CD có thể tự động hóa quy trình thử nghiệm và triển khai của bạn. Hãy xem cách sử dụng GitHub Actions để thiết lập quy trình CI/CD cơ bản.

Tạo tệp .github/workflows/ci-cd.yml trong thư mục gốc dự án của bạn:

tên: CI/CD bật: Push: nhánh: [ main ] pull_request: nhánh: [ main ] công việc: build-and-test: chạy trên: ubuntu-bước mới nhất: - sử dụng: actions/checkout@v2 - tên: Thiết lập .NET sử dụng: actions/setup-dotnet@v1 với: dotnet-version: '7.0.x' - tên: Khôi phục phụ thuộc chạy: khôi phục dotnet - tên: Chạy bản dựng: bản dựng dotnet --no-restore - tên: Chạy thử: dotnet test --no-build --verbosity triển khai bình thường: nhu cầu: chạy thử và xây dựng: ubuntu-latest if: github.ref == 'refs/heads/ main' các bước: - sử dụng: actions/checkout@v2 - name: Setup .NET use: actions/setup-dotnet@v1 with: dotnet-version: '7.0.x' - name: Publish run: dotnet Publish -c Release -o ./publish - name: Triển khai lên Azure Web App Sử dụng: azure/webapps-deploy@v2 với: app-name: 'your-app-name' pub-profile: ${{ secret.AZURE_WEBAPP_PUBLISH_PROFILE }} gói: ./publish

Quy trình công việc này sẽ chạy thử nghiệm mỗi khi bạn chuyển sang nhánh chính và nếu các thử nghiệm vượt qua, nó sẽ triển khai ứng dụng lên Azure Web App.

Bài tập thực hành: Triển khai API việc cần làm

Hãy triển khai API việc cần làm của chúng tôi lên Dịch vụ ứng dụng Azure.

  1. Trước tiên, hãy đảm bảo bạn có tài khoản Azure. Nếu không, bạn có thể tạo một tài khoản miễn phí.

  2. Trong Visual Studio, nhấp chuột phải vào dự án của bạn và chọn "Xuất bản".

  3. Chọn "Azure" làm tiêu điểm.

  4. Chọn "Dịch vụ ứng dụng Azure (Windows)".

  5. Nhấp vào "Tạo mới" để tạo Dịch vụ ứng dụng mới.

  6. Điền các thông tin cần thiết:

    • Tên ứng dụng: Chọn một tên duy nhất, chẳng hạn như "your-name-todo-api"
    • Đăng ký: Chọn đăng ký Azure của bạn
    • Nhóm tài nguyên: Tạo một nhóm mới hoặc chọn một nhóm hiện có
    • Gói lưu trữ: Tạo một gói mới hoặc chọn một gói hiện có (có sẵn cấp F1 miễn phí)
  7. Nhấp vào "Tạo" để tạo Dịch vụ ứng dụng.

  8. Sau khi tạo, nhấp vào "Xuất bản" để triển khai ứng dụng của bạn.

  9. Sau khi triển khai hoàn tất, Visual Studio sẽ mở một cửa sổ trình duyệt hiển thị URL API của bạn.

  10. Sử dụng Postman hoặc bất kỳ công cụ kiểm tra API nào để kiểm tra API của bạn. Ví dụ: bạn có thể gửi yêu cầu GET tới https://your-name-todo-api.azurewebsites.net/api/v1/todos để nhận tất cả các mục việc cần làm.

Chúc mừng! Bạn đã triển khai thành công ứng dụng MiniAPI của mình lên đám mây. Giờ đây, người dùng ở mọi nơi trên thế giới có thể truy cập API của bạn.

Hãy nhớ rằng, việc triển khai là một quá trình liên tục. Khi ứng dụng của bạn phát triển, bạn có thể cần phải cập nhật chiến lược triển khai của mình, có thể bao gồm việc thiết lập các quy trình CI/CD phức tạp hơn và triển khai các chiến lược nâng cao như triển khai xanh lam hoặc phát hành theo kiểu hoàng yến.

Trong chương tiếp theo, chúng ta sẽ khám phá một số vấn đề và giải pháp phổ biến cũng như các phương pháp hay nhất trong quá trình phát triển MiniAPI. Bạn đã sẵn sàng chưa? Hãy tiếp tục cuộc hành trình kỳ diệu của chúng tôi với MiniAPIs! .

13. Dự án thực tế: Đưa sự kỳ diệu của MiniAPI vào thực tế

Chào mừng bạn đến với Chương 13 của Khóa học ma thuật MiniAPIs của chúng tôi! Bây giờ bạn đã nắm vững các khái niệm cốt lõi và các tính năng nâng cao của MiniAPI, đã đến lúc áp dụng kiến thức này vào thực tế. Trong chương này, chúng tôi sẽ củng cố các kỹ năng của bạn thông qua ba dự án thực tế để bạn có thể thực sự trở thành bậc thầy ma thuật MiniAPI. Bạn đã sẵn sàng để bắt đầu cuộc phiêu lưu kỳ diệu này chưa? Hãy bắt đầu! .

Dự án 1: Xây dựng API quản lý tác vụ đơn giản

Dự án đầu tiên của chúng tôi là API quản lý tác vụ. API này sẽ cho phép người dùng tạo, đọc, cập nhật và xóa các tác vụ.

Bước 1: Tạo dự án

Đầu tiên, tạo một dự án MiniAPIs mới:

dotnet web mới -n TaskManagerApi cd TaskManagerApi

Bước 2: Thêm các gói cần thiết

gói thêm dotnet Microsoft.EntityFrameworkCore.InMemory

Bước 3: Tạo bối cảnh mô hình và dữ liệu

Tạo tệp Task.cs:

lớp công khai Nhiệm vụ { public int Id { get; set; } public string Title { get; } public string Mô tả { get; } public bool IsCompleted { get;

Tạo tệp TaskDbContext.cs:

sử dụng Microsoft.EntityFrameworkCore; lớp công khai TaskDbContext : DbContext { public TaskDbContext(DbContextOptions tùy chọn): cơ sở (tùy chọn) { } DbSet công khai Tasks { get;

Bước 4: Cấu hình dịch vụ và phần mềm trung gian

Cập nhật tệp Program.cs:

sử dụng Microsoft.EntityFrameworkCore; var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext(options => options.UseInMemoryDatabase("TaskList")); var app = builder.Build(); ); // Điểm cuối API sẽ được thêm vào đây app.Run();

Bước 5: Thêm điểm cuối API

Thêm các điểm cuối sau vào tệp Program.cs:

// Nhận tất cả các nhiệm vụ app.MapGet("/api/tasks", async (TaskDbContext db) => đang chờ db.Tasks.ToListAsync()); // Nhận một nhiệm vụ cụ thể app.MapGet("/api/tasks/{ id}", async (int id, TaskDbContext db) => đang chờ db.Tasks.FindAsync(id) là Nhiệm vụ nhiệm vụ ? Results.Ok(task) : Results.NotFound()); // Tạo một nhiệm vụ mới app.MapPost("/api/tasks", async (Nhiệm vụ nhiệm vụ, TaskDbContext db) => { db.Tasks.Add(task) ); đang chờ db.SaveChangesAsync(); trả về Results.Created($"/api/tasks/{task.Id}", task); }); // Cập nhật một tác vụ app.MapPut("/api/tasks/{id}", async (int id, Task inputTask, TaskDbContext db) => { var task = wait db.Tasks.FindAsync( id); nếu (tác vụ là null) trả về Results.NotFound(); task.IsCompleted = inputTask.IsCompleted; task.DueDate = inputTask.DueDate; đang chờ db.SaveChangesAsync(); return Results.NoContent() }); }", async (int id, TaskDbContext db) => { if (await db.Tasks.FindAsync(id) là Nhiệm vụ) { db.Tasks.Remove(task); đang chờ db.SaveChangesAsync(); return Results.Ok(task); } return Results.NotFound();

Bây giờ, bạn đã có API quản lý tác vụ đầy đủ chức năng! Bạn có thể sử dụng Postman hoặc bất kỳ công cụ kiểm tra API nào khác để kiểm tra các điểm cuối này.

Dự án 2: Xây dựng người dùng xác thực hệ thống

Dự án thứ hai của chúng tôi sẽ thêm chức năng xác thực người dùng vào API của chúng tôi. Chúng tôi sẽ sử dụng JWT (Mã thông báo web JSON) để đạt được điều này.

Bước 1: Thêm các gói cần thiết

dotnet thêm gói Microsoft.AspNetCore.Authentication.JwtBearer dotnet thêm gói System.IdentityModel.Tokens.Jwt

Bước 2: Tạo mô hình người dùng

Tạo tệp User.cs:

lớp công khai Người dùng { public int Id { get; } chuỗi công khai Tên người dùng { get; } chuỗi công khai Mật khẩu { get;

Bước 3: Cập nhật ngữ cảnh dữ liệu

Cập nhật TaskDbContext.cs:

lớp công khai TaskDbContext : DbContext { public TaskDbContext(DbContextOptions tùy chọn): cơ sở (tùy chọn) { } DbSet công khai Tasks { get; } public DbSet Users { get;

Bước 4: Cấu hình xác thực JWT

Thêm mã sau vào Program.cs:

sử dụng Microsoft.AspNetCore.Authentication.JwtBearer; sử dụng Microsoft.IdentityModel.Tokens; sử dụng System.Text; // ... mã hiện có ... builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options. TokenValidationParameters = TokenValidationParameters mới { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) }; var app = builder.Build(); app.UseAuthentication(); .mã hiện có...

Bước 5: Thêm điểm cuối đăng ký và đăng nhập của người dùng

Thêm các điểm cuối sau trong Program.cs:

sử dụng System.IdentityModel.Tokens.Jwt; sử dụng System.Security.Claims; sử dụng BCrypt.Net; // Đăng ký người dùng mới app.MapPost("/api/register", async (Người dùng người dùng, TaskDbContext db) => { var hiện cóUser = đang chờ db.Users.FirstOrDefaultAsync(u => u.Tên người dùng == người dùng.Tên người dùng); if (currentUser != null) trả về Results.BadRequest("Tên người dùng đã tồn tại"); user.PasswordHash = BCrypt.HashPassword(user.PasswordHash); db.Users.Add(user); .Created($"/api/users/{user.Id}", user }); app.MapPost("/api/login", async (mô hình LoginModel, TaskDbContext db, cấu hình IConfiguration) => { var user = chờ db.Users.FirstOrDefaultAsync(u => u.Username == model.Username); if ( người dùng == null || !BCrypt.Verify(model.Password, user.PasswordHash)) trả về Results.BadRequest("Tên người dùng hoặc mật khẩu không hợp lệ"); var token = GeneJwtToken(user, config); return Results.Ok(new { token } }); SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["Jwt:Key"])); thông tin xác thực var = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); var Claims = new[] { new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), new Claim(ClaimTypes.Name, user.Username) }; (nhà phát hành: config["Jwt:Issuer"], đối tượng: config["Jwt:Audience"], xác nhận quyền sở hữu: xác nhận quyền sở hữu, hết hạn: DateTime.Now.AddMinutes(15), signatureCredentials: thông tin đăng nhập); trả về JwtSecurityTokenHandler().WriteToken(token) mới ; đặt; } mật khẩu chuỗi công khai { lấy;

Bước 6: Bảo mật API quản lý tác vụ

Cập nhật điểm cuối của API quản lý tác vụ và thêm thuộc tính [Ủy quyền]:

app.MapGet("/api/tasks", [Authorize] async (TaskDbContext db) => đang chờ db.Tasks.ToListAsync()); // ...thực hiện các thay đổi tương tự cho các điểm cuối khác...

Bây giờ API của bạn đã có hệ thống xác thực người dùng! Người dùng cần đăng ký trước, sau đó đăng nhập để nhận mã thông báo JWT và cuối cùng sử dụng mã thông báo để truy cập API quản lý tác vụ được bảo vệ.

Dự án thứ ba: Xây dựng Blog API

Dự án thứ ba của chúng tôi là API viết blog. API này sẽ cho phép người dùng tạo, đọc, cập nhật và xóa các bài đăng trên blog cũng như thêm nhận xét.

Bước 1: Tạo mô hình

Tạo tệp BlogPost.cs và Comment.cs:

lớp công khai BlogPost { public int Id { get; } public string Title { get; } public string Nội dung { get; ; } = Danh sách mới(); } lớp công khai Nhận xét { public int Id { get; set; } public string Nội dung { get; int BlogPostId { get; bộ } public BlogPost BlogPost { get;

Bước 2: Cập nhật ngữ cảnh dữ liệu

Cập nhật TaskDbContext.cs:

lớp công khai BlogDbContext : DbContext { public BlogDbContext(DbContextOptions tùy chọn): cơ sở (tùy chọn) { } DbSet công khai BlogPosts { get;

Bước 3: Thêm điểm cuối API

Thêm các điểm cuối sau trong Program.cs:

// Lấy tất cả các bài đăng trên blog app.MapGet("/api/posts", async (BlogDbContext db) => đang chờ db.BlogPosts.Include(p => p.Comments).ToListAsync()); // Lấy một blog cụ thể đăng app.MapGet("/api/posts/{id}", async (int id, BlogDbContext db) => đang chờ db.BlogPosts.Include(p => p.Comments).FirstOrDefaultAsync(p => p.Id == id) là bài đăng BlogPost ? Results.Ok(post) : Results.NotFound()); đăng app.MapPost("/api/posts", async (bài đăng BlogPost, BlogDbContext db) => { post.CreatedAt = DateTime.UtcNow; db.BlogPosts.Add(post); đang chờ db.SaveChangesAsync(); return Results.Created($"/api/posts/{post.Id}", post }); đăng ứng dụng.MapPut("/api/posts/{id}", async (int id, BlogPost inputPost, BlogDbContext db) => { var post = chờ db.BlogPosts.FindAsync(id); if (bài đăng rỗng) return Results.NotFound(); ); return Results.NoContent() }); app.MapDelete("/api/posts/{id}", async (int id, BlogDbContext db) => { if (await db.BlogPosts.FindAsync(id) là bài đăng BlogPost) { db.BlogPosts.Remove(post) ; đang chờ db.SaveChangesAsync(); return Results.Ok(post } return); Results.NotFound(); }); // Thêm nhận xét vào bài đăng trên blog app.MapPost("/api/posts/{postId}/comments", async (int postId, Comment comment, BlogDbContext db) => { var post = đang chờ db.BlogPosts.FindAsync(postId); nếu (bài đăng rỗng) trả về Results.NotFound(); postId; comment.CreatedAt = DateTime.UtcNow; db.Comments.Add(comment); đang chờ db.SaveChangesAsync(); , bình luận); }); // Lấy tất cả các bình luận cho một bài đăng trên blog app.MapGet("/api/posts/{postId}/comments", async (int postId, BlogDbContext db) => { var post = wait db.BlogPosts.FindAsync(postId); if (bài đăng rỗng) trả về Kết quả. NotFound(); var comments = đang chờ db.Comments .Where(c => c.BlogPostId == postId) .ToListAsync(); return Results.Ok(comments); }); // Xóa bình luận app.MapDelete("/api/comments/{id}", async (int id, BlogDbContext db) => { if (await db.Comments.FindAsync(id) là Nhận xét bình luận) { db.Comments.Remove(comment); db.SaveChangesAsync(); trả về Results.Ok(comment); } return Results.NotFound();

Bây giờ, bạn đã có API viết blog đầy đủ chức năng! API này cho phép người dùng tạo, đọc, cập nhật và xóa các bài đăng trên blog cũng như thêm và xóa nhận xét.

Bước 4: Thêm chức năng phân trang

Để tối ưu hóa hiệu suất, chúng tôi có thể thêm chức năng phân trang vào điểm cuối tìm nạp các bài đăng trên blog:

// Nhận tất cả các bài đăng trên blog bằng cách phân trang app.MapGet("/api/posts", async (int page = 1, int pageSize = 10, BlogDbContext db) => { var TotalPosts = wait db.BlogPosts.CountAsync(); var TotalPages = (int)Math.Ceiling(totalPosts / (double)pageSize); db.BlogPosts .Include(p => p.Comments) .Skip((page - 1) * pageSize) .Take(pageSize) .ToListAsync(); return Results.Ok(new { Bài viết = bài viết, CurrentPage = trang, TotalPages = TotalPages, PageSize = pageSize, TotalPosts = TotalPosts } });

Bước 5: Thêm chức năng tìm kiếm

Chúng tôi cũng có thể bổ sung thêm các chức năng tìm kiếm cho phép người dùng tìm kiếm các bài đăng trên blog dựa trên tiêu đề hoặc nội dung phân:

// Tìm kiếm bài đăng trên blog app.MapGet("/api/posts/search", async (truy vấn chuỗi, BlogDbContext db) => { var post = wait db.BlogPosts .Where(p => p.Title. Chứa(truy vấn) || p.Content.Contains(query)) .Include(p => p.Comments) .ToListAsync(); Results.Ok(bài viết);

Bước 6: Thêm thẻ chức năng

Vui lòng thêm thẻ chức năng vào bài đăng trên blog của chúng tôi:

Đầu tiên, tạo Tag mô hình:

lớp công khai Tag { public int Id { set } Tên chuỗi công khai { get } public List BlogPosts { get;

Sau đó, cập nhật mô hình BlogPost:

public class BlogPost { // ...thuộc tính hiện có ... public List Thẻ { nhận được;

Cập nhật dữ liệu bối cảnh:

lớp công khai BlogDbContext : DbContext { // ... thuộc tính DbSet hiện có ... thẻ DbSet công khai { get; } ghi đè được bảo vệ void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity() .HasMany(p => p.Tags) .WithMany(t => t.BlogPosts) .UsingEntity(j => j.ToTable("BlogPostTags"));

Thêm điểm liên kết cuối cùng vào thẻ:

// Thêm thẻ vào bài đăng trên blog app.MapPost("/api/posts/{postId}/tags", async (int postId, List tagNames, BlogDbContext db) => { var post = wait db.BlogPosts. FindAsync(postId); if (bài viết trống) trả về Results.NotFound(); (var tagName in tagNames) { var tag = đang chờ db. Tags.FirstOrDefaultAsync(t => t.Name == tagName); if (tag là null) { tag = Thẻ mới { Tên = tagName }; } đang chờ db.SaveChangesAsync(); .MapGet("/api/tags", async (BlogDbContext db) => đang chờ db.Tags.ToListAsync()); // Nhận bài đăng theo thẻ app.MapGet("/api/posts/bytag/{tagName}" , không đồng bộ (chuỗi tagName, BlogDbContext db) => { var post = chờ db.BlogBài viết .Where(p => p.Tags.Any(t => t.Name == tagName)) .Include(p => p.Comments) .Include(p => p.Tags) .ToListAsync(); trả về kết quả .Ok(bài viết);

API viết blog nâng cấp này hiện bao gồm các tính năng sau:

  1. Các thao tác CRUD cơ bản cho bài đăng và nhận xét trên blog
  2. Chức năng phân trang để xử lý khối lượng lớn bài đăng trên hiệu quả blog hơn
  3. Chức năng tìm kiếm cho phép người dùng tìm kiếm các bài đăng trên blog dựa trên tiêu đề hoặc nội dung
  4. Chức năng gắn thẻ cho phép thêm thẻ vào bài đăng trên blog và xuất bài viết dựa trên thẻ

Dự án này trình bày cách sử dụng MiniAPI để xây dựng một API tương phản phức tạp, bao gồm các liên kết dữ liệu (bài đăng và nhận xét trên blog), mối quan hệ nhiều-nhiều (bài đăng trên blog và thẻ) cũng như các hoạt động truy vấn nâng cao cao hơn.

Bằng cách hoàn thành dự án này, bạn đã có kinh nghiệm thực tế khi sử dụng MiniAPI để xây dựng nhiều loại API khác nhau. link, phân trang, tìm kiếm và gắn thẻ.

Hãy nhớ rằng, hãy luyện tập là khóa để thành công bất kỳ kỹ thuật nào. mới vào dự án này hoặc bắt đầu các tính năng của riêng bạn. thành lớp thực thi MiniAPI được phép!

Trong chương tiếp theo, chúng tôi sẽ thảo luận về một số vấn đề phổ biến và giải pháp của chúng cũng như các phương pháp hay nhất trong quá trình phát triển MiniAPI.

14. Các câu hỏi và giải pháp thường gặp: Khắc phục sự cố bất kỳ cho MiniAPI

Chào mừng bạn đến với Chương 14 Khóa học ma thuật MiniAPIs của chúng tôi! Ngay cả những pháp sư lành nghề nhất cũng có thể must a number of problem phức tạp. cần phải sử dụng MiniAPI và cách giải quyết. Hãy bắt đầu quá trình giải quyết vấn đề MiniAPI của chúng tôi!

Các lỗi và giải pháp thường gặp

1. Định tuyến xung

Cố gắng: Có thể định tuyến xung đột đường dẫn tuyến tính mẫu.

Giải thích:

  • Đảm bảo đường dẫn là duy nhất cho mỗi điểm cuối.
  • Sử dụng các phương thức HTTP khác nhau để phân biệt các đường tương tự tuyến tính.
  • Sử dụng các đường dẫn tuyến tính bắt buộc để phân biệt rõ hơn các đường tuyến.

Ví dụ:

app.MapGet("/api/items/{id:int}", (int id) => $"Nhận mục theo ID: {id}"); , (tên chuỗi) => $"Lấy mục theo tên: {name}");

2. Vấn đề chia sẻ tài nguyên giữa các nguồn gốc (CORS)

Sự cố: Front-end ứng dụng có thể gặp lỗi CORS khi cố gắng truy cập API của bạn từ một miền khác.

Giải thích:

  • Định cấu hình CORS trong ứng dụng của bạn.
var builder = WebApplication.CreateBuilder(args); builder.Services.AddCors(options => { options.AddPolicy("AllowSpecificOrigin", builder => builder.WithOrigins("http://example.com") .AllowAnyHeader() . AllowAnyMethod()); }); app.UseCors("AllowSpecificOrigin"); ... các cấu hình định tuyến và các phần mềm trung gian khác

3. Cơ sở dữ liệu kết nối vấn đề

Sự cố: Không thể kết nối với cơ sở dữ liệu hoặc thực hiện các thao tác với cơ sở dữ liệu.

Giải thích:

  • Kiểm tra kết nối chuỗi xem có sai không.
  • Đảm bảo cơ sở dữ liệu máy chủ đang chạy và có thể truy cập được.
  • Sử dụng ngoại lệ xử lý để phát hiện và ghi lại cơ sở dữ liệu lỗi.
app.MapGet("/api/items", async (MyDbContext db) => { try { return wait db.Items.ToListAsync(); } Catch (Exception ex) { // Ghi lại lỗi Console.WriteLine($"Database error : {ex.Message}"); return Results.Problem("Đã xảy ra lỗi khi tải dữ liệu."); } });

4. Vấn đề xác thực và ủy quyền

Sự cố: Người dùng không thể xác thực chính xác hoặc truy cập các tài nguyên được bảo vệ.

Giải thích:

  • Đảm bảo phần mềm trung gian xác thực được cấu hình chính xác.
  • Kiểm tra xem chữ ký và xác nhận quyền sở hữu của mã thông báo JWT có chính xác không.
  • Sử dụng hợp các quyền thuộc tính để bảo mật điểm cuối.
app.MapGet("/api/protected", [Authorize] (ClaimsPrincipal user) => { var userId = user.FindFirst(ClaimTypes.NameIdentifier)?.Value; return $"Xin chào, người dùng {userId}!"; }) ;

5. Giải quyết buộc mô hình

Sự cố: API không thể liên kết chính xác các nội dung yêu cầu hoặc tham số phức tạp.

Giải thích:

  • Đảm bảo nội dung được yêu cầu hoặc tham số truy vấn phù hợp với mô hình cấu hình của bạn.
  • Sử dụng tùy chỉnh cấu hình Gmail chất để xử lý các vấn đề liên quan phức tạp.
app.MapPost("/api/complex", (ComplexModel model) => { if (!ModelState.IsValid) { return Results.ValidationProblem(ModelState); } // Xử lý mô hình chuỗi công khai... }); Tên { get; } public int Age { get } Danh sách công khai Thẻ { get;

Các phương pháp hay nhất phát triển mạnh mẽ MiniAPI

  1. Sử dụng thuộc tính phụ thuộc của nội dung: ASP.NET Core để quản lý vòng đời dịch vụ và các phần phụ thuộc.
builder.Services.AddScoped();
  1. Thực hiện hợp lý lỗi xử lý: Sử dụng phần mềm xử lý trung gian ngoại lệ toàn cầu để bắt và xử lý các ngoại lệ chưa được xử lý.
app.Use(async (context, next) => { try { wait next(context); } Catch (Exception ex) { context.Response.StatusCode = 500; đang chờ context.Response.WriteAsJsonAsync(new { error = "One điều kiện không được mong đợi xảy ra lỗi." }); } });
  1. Use a not clock: Sử dụng các phương pháp không đồng bộ bất cứ khi nào có thể để cải thiện hiệu suất và khả năng mở rộng của ứng dụng.
app.MapGet("/api/items", async (MyDbContext db) => đang chờ db.Items.ToListAsync());
  1. Thực hiện hợp lý nhật ký: Sử dụng hợp nhất nhật ký hệ thống để ghi lại các sự kiện và lỗi quan trọng.
app.MapGet("/api/items", (ILogger logger) => { logger.LogInformation("Đang tìm tất cả các mục"); // ... logic để lấy các mục});
  1. Sử dụng mô hình xác thực: Sử dụng chú thích dữ liệu hoặc FluentValidation để xác thực đầu vào dữ liệu.
app.MapPost("/api/items", async (Mục vật phẩm, IValidator validator) => { var validationResult = chờ validator.ValidateAsync(item); if (!validationResult.IsValid) { return Results.ValidationProblem(validationResult .ToDictionary()); logic để xử lý hợp lệ các mục });
  1. Sử dụng hợp nhất HTTP trạng thái mã hóa: Đảm bảo API của bạn trả về chính xác trạng thái HTTP mã hóa.
app.MapGet("/api/items/{id}", (int id) => { var item = GetItemById(id); if (item == null) return Results.NotFound(); return Results.Ok(item ); });
  1. Triển khai kiểm tra API phiên bản: Hãy cân nhắc việc cài đặt phiên bản API ngay từ đầu để có thể dễ dàng thực hiện các thay đổi trong tương lai.
app.MapGet("/api/v1/items", () => "Các mục phiên bản 1"); app.MapGet("/api/v2/items", () => "Các mục phiên bản 2" );
  1. Use quy ước đặt tên phù hợp: Use quy định đặt tên rõ ràng và tối thiểu cho điểm cuối, mô hình và dịch vụ của bạn.

  2. Triển khai bộ đệm: Đối với dữ liệu được truy cập thường xuyên Ít nhưng thay đổi, hãy cân nhắc phát triển khai bộ bộ đệm để cải thiện hiệu suất.

app.MapGet("/api/items", async (IMemoryCache cache) => { return wait cache.GetOrCreateAsync("all_items", async entry => { entry.SetAbsoluteExpiration(TimeSpan.FromMinutes(10)); // .. . Logic lấy các mục từ cơ sở dữ liệu dữ liệu} });
  1. Sử dụng kiểm tra sức khỏe: Triển khai trạng thái kiểm tra điểm cuối cùng để theo dõi trạng thái API của bạn.
builder.Services.AddHealthChecks(); // ... app.MapHealthChecks("/health");

Bằng cách làm theo các phương pháp hay nhất này và hiểu cách giải quyết các vấn đề thường gặp, bạn sẽ có thể xây dựng các ứng dụng MiniAPI mạnh mẽ, hiệu quả và dễ bảo trì hơn. thuật toán của MiniAPI cần có thời gian và luyện tập. có thể xử lý các API phát triển công thức khác nhau một cách dễ dàng.

You đã sẵn sàng chưa?

15. API nhỏ

Chào mừng bạn đến với chương trình cuối cùng của Khóa học ma thuật MiniAPIs của chúng tôi Giống như mọi thuật sĩ giỏi đều Trọng chương trình này, chúng ta sẽ khám phá một số tài nguyên có giá trị, các diễn đàn cộng đồng và các tài liệu được xuất ra Hãy cùng nhau khám phá vòng tròn kỳ diệu của MiniAPI!

Chính thức tài liệu và tài nguyên

  1. Tài liệu chính thức của Microsoft: Đây là tài nguyên bạn có thể truy cập. Tiếp tục cho MiniAPI.

  2. Kho lưu trữ ASP.NET Core GitHub: Tại đây bạn có thể xem tiến trình phát triển mới nhất, báo cáo sự cố và thậm chí đóng góp mã hóa. https://github.com/dotnet/aspnetcore.

  3. https://www.youtube.com/dotnet .

  4. Microsoft Learn: https://docs.microsoft.com/en-us/learn/.

Diễn đàn cộng đồng và thảo luận nhóm

  1. Stack Overflow: Đây là một trong những nền tảng phổ biến nhất dành cho các nhà phát triển câu hỏi và trả lời các câu hỏi Sử dụng thẻ. "asp.net-core" và "minimal-api" để tìm các vấn đề liên quan https://stackoverflow.com/questions/tagged/asp.net-core+minimal-api.

  2. Cộng đồng r/dotnet và r/csharp của Reddit: Các subreddits này là các cộng đồng tích cực thảo luận về các chủ đề liên quan đến .NET. https://www.reddit.com/r/dotnet/ https://www.reddit.com/r/csharp/ .

  3. ASP.NET Core Gitter: ASP.NET Core Gitter https://gitter.im/aspnet/Home.

  4. Cộng đồng .NET trên Discord: Có nhiều cộng đồng nhà phát triển .NET đang hoạt động trên Discord.

  5. Công nghệ Microsoft thảo luận về .NET và ASP.NET Core https://techcommunity.microsoft.com/t5/net/ct-p/dotnet.

Blog và nguồn tin tức

  1. Blog của Scott Hanselman: Scott là Giám đốc chương trình chính tại Microsoft và blog của anh ấy thường chứa các bài viết chuyên sâu về ASP.NET Core. https://www.hanselman.com/blog/.

  2. Blog của Andrew Lock: Blog của Andrew tập trung vào ASP.NET Core và chứa nhiều bài viết kỹ thuật chuyên sâu https://andrewlock.net/ .

  3. Blog .NET: Đây là blog .NET chính thức của Microsoft, thường xuyên có các thông báo về các tính năng và bản cập nhật mới https://devblogs.microsoft.com/dotnet/ .

  4. Thông báo C#: C# và .NET.

Sách và các khóa học trực tuyến

  1. "ASP.NET Core in Action" Andrew Lock: Cuốn sách này cung cấp cái nhìn sâu sắc về ASP.NET Core, bao gồm cả MiniAPI.

  2. Các khóa học ASP.NET Core của Pluralsight: Pluralsight cung cấp nhiều khóa học video ASP.NET Core chất lượng cao.

  3. Khóa học ASP.NET Core MiniAPIs trên Udemy: Có rất nhiều khóa học thực hành về MiniAPI trên Udemy.

  4. Các khóa học .NET tại LinkedIn Learning: LinkedIn Learning (trước đây là Lynda.com) cung cấp một số khóa học về .NET và ASP.NET Core.

Tiện ích mở rộng công cụ và tiện ích

  1. Visual Studio: IDE chính của Microsoft, cung cấp hỗ trợ hỗ trợ tuyệt vời cho việc phát triển .NET.

  2. Visual Studio Code: Trình chỉnh sửa nhẹ nhưng mạnh mẽ có thể hỗ trợ tốt việc phát triển MiniAPI với các tiện ích mở rộng C#.

  3. JetBrains Rider: Một .NET IDE phổ biến khác cung cấp nhiều tính năng thông minh.

  4. Người đưa thư: Một công cụ kiểm tra API mạnh mẽ hữu ích để phát triển và thử nghiệm MiniAPI.

  5. Swagger/OpenAPI: MiniAPI.

Những ý nghiên cứu tiếp theo

  1. Tìm hiểu chuyên sâu về C#: MiniAPI được xây dựng trên C#. phát triển MiniAPI tốt hơn.

  2. Tìm hiểu Entity Framework Core: Là ORM phổ biến nhất trong hệ sinh thái .NET, EF Core thường được sử dụng với MiniAPI.

  3. Khám phá các thiết kế mẫu: Hiểu các phổ biến thiết kế mẫu có thể giúp bạn thiết kế các cấu trúc API tốt hơn.

  4. API API API RESTful của bạn nhất quán hơn và dễ sử dụng hơn.

  5. Mini API của bạn có thể giúp API của bạn nhanh hơn và hiệu quả hơn result than.

  6. Khám phá kiến ​​trúc dịch vụ: MiniAPI rất phù hợp để xây dựng dịch vụ và hiểu kiến ​​trúc dịch vụ có thể mở ra những khả năng mới.

Hãy nhớ rằng, trở thành bậc thầy ma thuật MiniAPIs là một quá trình học hỏi liên tục. Thế giới công nghệ luôn thay đổi và duy nhất. tiến độ tò mò cũng như niềm đam mê học hỏi là điều quan trọng. thảo luận trong cộng đồng và tiếp tục thực hiện và thử nghiệm.

Bạn đã hoàn thành Khóa học ma thuật MiniAPIs của chúng tôi! bạn. nhiên!

Hãy tận dụng niềm vui trong thế giới kỳ diệu của MiniAPI và tạo ra các API tuyệt vời! Nếu bạn có bất kỳ câu hỏi nào, hãy sử dụng! hãy nhớ rằng cộng đồng và các tài nguyên này luôn hỗ trợ bạn.

Cuối cùng, bài viết về cách bắt đầu học .NET8 MiniApis đã kết thúc tại đây. học .NET8MiniApis, vui lòng tìm kiếm các bài viết về CFSDN hoặc tiếp tục duyệt các bài viết liên quan. hộ blog của tôi trong tương lai .

58 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress