- VisualStudio2022
- pprof-Hướng dẫn sử dụng nó trong bản mạng trực tiếp
- Triển khai C# các loại hộp chọn nhiều màu lựa chọn thả xuống, cây lựa chọn nhiều màu lựa chọn thả xuống và các nút tối đa
- [Ghi chú học tập] Cơ sở dữ liệu cấu trúc: cat tree
Đâ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 .
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.
Đơ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.
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.
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.
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.
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
Đơn giản MiniAPI được thiết kế riêng cho các vấn đề sau:
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ả.
Mini API cho phép bạn xây dựng một mô hình hoạt động trong vài phút.
Ứ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.
Bạn có thể dễ dàng tạo ra các hàm đáp ứng API.
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!
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!
API nhỏ:
hệ điều hành:
Phần cứng yêu cầu:
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.
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:
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.
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.
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.
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.
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:
Đ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ố.
Visual Studio Code, tôi khuyên bạn nên cài đặt tiện ích mở rộng tiện ích sau:
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.
Dự án mở: Mở dự án bạn vừa tạo bằng IDE bạn chọn.
mã MyFirstMiniAPI
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!
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!
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:
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.
Đ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.
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.
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ý.
Hãy xem xét các khái niệm chính chi tiết hơn:
Đ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.
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ý.
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ệ.
Đị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.
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ụ.
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:
so với ASP.NET Core MVC truyền thống:
so với Express.js (Node.js):
so với Bình (Python):
so với FastAPI (Python):
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! .
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ã! .
Đầ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.
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.json
Và appsinstall.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.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:
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):
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.
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.
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!
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 .
Trong MiniAPI đường khác nhau:
Đị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.
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ý.
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).
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.
MiniAPI cung cấp một cách dễ dàng để xử lý các phương thức HTTP khác nhau:
Chúng thường được sử dụng để lấy dữ liệu:
app.MapGet("/api/products", () => new[] { "Product1", "Product2", "Product3" });
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 });
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(); });
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(); });
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:
Đườ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.
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.
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.
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! .
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! .
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.
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.
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.
Đố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.
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ủ.
MiniAPI cung cấp nhiều cách để trả lại dữ liệu cho khách hàng.
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" });
Đố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.
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.
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.
Đâ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.
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.
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! .
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! .
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:
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ể.
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.
Để
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.
Đôi khi, bạn có thể muốn trả lời tùy chỉnh phản hồi lỗi.
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." } }); ;
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ự);
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ý.
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:
Kết quả.Problem()
Trả về phản hồi lỗi đã được chuẩn hóa.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!
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.
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:
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.
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.
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.
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:
Luôn sử dụng HTTPS để mã hóa dữ liệu khi truyền:
app.UseHttpsRedirection();
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();
Luôn luôn
app.MapPost("/api/comments", (CommentInput input) => { var cleanComment = System.Web.HttpUtility.HtmlEncode(input.Comment); // ;
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 });
Lõi MiniAPI ASP.NET.
Đầ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();
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}!"; });
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!"; });
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:
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!
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é!
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;"
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.
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); });
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 });
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();
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();
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:
Tuy nhiên, có một số lưu ý khi sử dụng ORM:
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:
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!
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é!
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.
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();
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();
MiniAPI có thể dễ dàng xử lý các hoạt động tải lên và tải xuống tệp.
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." });
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); });
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.
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ụ.
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();
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); });
API nhỏ mở rộng ứng dụng.
app.MapGet("/api/data", async (IMyAsyncService myService) => { var data = chờ myService.GetDataAsync(); return Results.Ok(data); });
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:
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! .
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 .
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.
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.
.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ố.
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.
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.
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 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:
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.
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.
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.
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.
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.
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.
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:
Việ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... }
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
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:
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!
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!
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ộ.
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ó.
xuất bản
folder.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.
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.
Ngoài ra, bạn có thể sử dụng Azure CLI:
az webapp up --sku F1 --name --os-type windows
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
Cài đặt Heroku CLI và đăng nhập.
Tạo một ứng dụng Heroku mới:
heroku tạo tên ứng dụng của bạn
Thiết lập gói xây dựng:
gói xây dựng heroku: set jincod/dotnetcore
Triển khai ứng dụng của bạn:
git đẩy heroku chính
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.
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.
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í.
Trong Visual Studio, nhấp chuột phải vào dự án của bạn và chọn "Xuất bản".
Chọn "Azure" làm tiêu điểm.
Chọn "Dịch vụ ứng dụng Azure (Windows)".
Nhấp vào "Tạo mới" để tạo Dịch vụ ứng dụng mới.
Điền các thông tin cần thiết:
Nhấp vào "Tạo" để tạo Dịch vụ ứng dụng.
Sau khi tạo, nhấp vào "Xuất bản" để triển khai ứng dụng của bạn.
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.
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! .
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 đầ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ụ.
Đầu tiên, tạo một dự án MiniAPIs mới:
dotnet web mới -n TaskManagerApi cd TaskManagerApi
gói thêm dotnet Microsoft.EntityFrameworkCore.InMemory
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;
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();
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 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.
dotnet thêm gói Microsoft.AspNetCore.Authentication.JwtBearer dotnet thêm gói System.IdentityModel.Tokens.Jwt
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;
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;
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ó...
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;
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 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.
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;
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;
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.
Để 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 } });
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);
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:
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.
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ố gắng: Có thể định tuyến xung đột đường dẫn tuyến tính mẫu.
Giải thích:
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}");
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:
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
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:
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."); } });
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:
app.MapGet("/api/protected", [Authorize] (ClaimsPrincipal user) => { var userId = user.FindFirst(ClaimTypes.NameIdentifier)?.Value; return $"Xin chào, người dùng {userId}!"; }) ;
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:
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;
builder.Services.AddScoped();
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." }); } });
app.MapGet("/api/items", async (MyDbContext db) => đang chờ db.Items.ToListAsync());
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});
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 });
app.MapGet("/api/items/{id}", (int id) => { var item = GetItemById(id); if (item == null) return Results.NotFound(); return Results.Ok(item ); });
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" );
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.
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} });
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?
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!
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.
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.
https://www.youtube.com/dotnet .
Microsoft Learn: https://docs.microsoft.com/en-us/learn/.
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.
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/ .
ASP.NET Core Gitter: ASP.NET Core Gitter https://gitter.im/aspnet/Home.
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.
Công nghệ Microsoft thảo luận về .NET và ASP.NET Core https://techcommunity.microsoft.com/t5/net/ct-p/dotnet.
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/.
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/ .
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/ .
Thông báo C#: C# và .NET.
"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.
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.
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.
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.
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.
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#.
JetBrains Rider: Một .NET IDE phổ biến khác cung cấp nhiều tính năng thông minh.
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.
Swagger/OpenAPI: MiniAPI.
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.
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.
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.
API API API RESTful của bạn nhất quán hơn và dễ sử dụng hơn.
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.
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 .
Hive - Giới thiệu về Hive Apache Hive là một nguồn kho dữ liệu hệ thống được xây dựng trên Hadoop. Dữ liệu có cấu trúc và bán cấu trúc được lưu trữ trong Hadoop tệp vào cơ sở dữ liệu bảng.
HBase bài viết của Google "Bigtable: Hệ thống lưu trữ phân tán cho dữ liệu có cấu trúc" do Fay Chang viết.
Zero: Hiện trạng thái của front-end Lịch sử phát triển front-end HTML(5), CSS(3), JavaScript(ES5, ES6): Viết từng trang -> cho back-end (PHP, Python, Go, Java ) ->
JavaScript là trình lập ngôn ngữ JavaScript trên máy tính của mình. JavaScript từng được sử dụng chủ yếu để làm cho các trang web có tính tương tác
Tôi từng là một người mới vào nghề, chưa biết gì về quy trình thiết lập nhưng được cung cấp bởi sự tò mò và khao khát kiến trúc thức về thế giới Internet, tôi đã bước chân vào chương trình cài đặt. chương trình kỳ kỳ - Python.
Bạn đã có một số trường hợp lý về trình thu thập dữ liệu Python. phải lo lắng về việc lấy dữ liệu từ một trang web cụ thể chưa? sử dụng cho riêng bạn? Vâng, bài viết này sẽ cung cấp cho bạn một số nguồn cảm hứng và cảm hứng.
đóng cửa. Câu hỏi này dựa trên ý kiến. câu hỏi này có tốt không? . Đã đóng cửa 8 năm trước.
Tôi muốn tạo một ứng dụng như https://apprtc.appspot.com/?r=04188292. Tôi biết chút về webrtc nhưng không thể hiểu được google app-engine. làm thế nào để java
Tôi mới bắt đầu sử dụng Python và viết một chương trình ngoại vi đơn giản. >>> time point
Redis có 5 cơ sở dữ liệu cấu trúc là string, list, hash, set và zset. nhất trong quá trình phát triển hàng ngày. kiến thức về ứng dụng Redis.
Các bước có thể tạo và xuất bản một trang web dự án: 1. Tạo một trang web dự án helloword trong công cụ phát triển 2. Tạo tệp index.html trong webContent 3. Xuất bản ứng dụng web lên
Nếu bạn sử dụng thiết bị đầu cuối trên Ubuntu trong một khoảng thời gian dài, bạn có thể muốn điều chỉnh phông chữ và kích thước kích thước của thiết bị cuối cùng để có trải nghiệm tốt. nhưng trực quan nhất để tùy chỉnh thiết bị Linux cuối cùng của bạn cho tôi.
1. Giới thiệu ADODB là tên viết tắt của Active Data Objects Data Base. SFS3 system system (Mạng lưới hệ thống học thuật trao đổi phần mềm miễn phí trong trường user) đã được lên kế hoạch
Tôi hoàn toàn mới làm quen với neo4j và tôi xin lỗi vì đã hỏi một câu hỏi cơ bản như vậy. use shell "localhost:7474/webadmin/#/console/"
Tôi đang đọc Core Audio cho iOS 4 với mục đích xây dựng một ứng dụng thử nghiệm nhỏ. Tại thời điểm này, tôi rất bối rối với tất cả các nghiên cứu về api. Lý tưởng nhất là tôi muốn biết cách trích xuất một số mẫu từ hai bản mp3 thành một mảng. và sau đó trong vòng lặp gọi lại
đóng cửa. Câu hỏi này không có thủ tục nguyên tắc của Stack Overflow. Stack Overflow vì Stack Overflow vì
Tôi đã tải xuống GNUStep và cài đặt nó nhưng tôi không biết tìm IDE ở đâu. Có ai biết chương trình nào có thể được sử dụng làm GNUStep IDE/lấy chúng ở đâu không? Mặt khác, có ai biết gì về cách tạo và biên dịch chương trình GNUStep cơ bản không
Tôi đang cố gắng bắt đầu sử dụng Apache Solr, nhưng có một số điều tôi chưa hiểu rõ. Đọc qua hướng dẫn, tôi đã thiết lập một phiên bản Solr đang chạy. Điều khiến tôi bối rối là tất cả cấu hình (lược đồ, v.v.) của Solr đều ở định dạng XML.
Có tài liệu nào về cách bắt đầu sử dụng BruTile không? Tôi hiện đang sử dụng SharpMap và tôi cần lưu trước các ô vào bộ đệm để tăng tốc quá trình Câu trả lời hay nhất Tôi đang làm việc này hôm nay :) Trang web dự án Mapsui phụ thuộc rất nhiều vào SharpMap
Cố gắng hết sức nhưng tôi không thể yêu cầu CEDET làm bất cứ điều gì. Emac 24.3. Tôi đã tải xuống ảnh chụp nhanh CEDET mới nhất. Tôi lấy phần thiết lập của Alex Ott từ phía dưới của anh ấy (không phải vậy) Giới thiệu nhẹ nhàng
Tôi là một lập trình viên xuất sắc, rất xuất sắc!