文章目錄
- 項目地址
- 一、異常處理
- 1.1 自定異常
- 1.2 自定義異常處理中間件
- 1.3 注冊中間件
- 二、grpc服務
- 2.1 創建protos
- 1. 打折的protos
- 2. 設置grpc server
- 3. program配置服務
- 4. docker-compose
- 2.2 CRUD
- 1. 查詢
- 2.3 測試
- 1. 發起查詢請求
- 三、grpc服務消費
- 3.1 創建client
- 1. 添加服務
- 2. 選擇需要添加的服務類型
- 3. 選擇服務路徑
- 4. 添加成功后
- 5. Program里添加Client服務
- 6. appSettings里添加grpc服務地址
- 3.2 grpc通訊
- 1. 在StoreBasketCommandHandler使用
項目地址
- 教程作者:
- 教程地址:
- 代碼倉庫地址:
- 所用到的框架和插件:
dbt
airflow
一、異常處理
1.1 自定異常
- BadRequestException
- InternalServerException
- NotFoundException
1.2 自定義異常處理中間件
- 異常處理中間件
public class CustomExceptionHandler(ILogger<CustomExceptionHandler> logger): IExceptionHandler
{public async ValueTask<bool> TryHandleAsync(HttpContext context, Exception exception, CancellationToken cancellationToken){logger.LogError("Error Message: {exceptionMessage}, Time of occurrence {time}",exception.Message, DateTime.UtcNow);(string Detail, string Title, int StatusCode) details = exception switch{InternalServerException =>(exception.Message,exception.GetType().Name,context.Response.StatusCode = StatusCodes.Status500InternalServerError),ValidationException =>(exception.Message,exception.GetType().Name,context.Response.StatusCode = StatusCodes.Status400BadRequest),BadRequestException =>(exception.Message,exception.GetType().Name,context.Response.StatusCode = StatusCodes.Status400BadRequest),NotFoundException =>(exception.Message,exception.GetType().Name,context.Response.StatusCode = StatusCodes.Status404NotFound),_ =>(exception.Message,exception.GetType().Name,context.Response.StatusCode = StatusCodes.Status500InternalServerError)};var problemDetails = new ProblemDetails{Title = details.Title,Detail = details.Detail,Status = details.StatusCode,Instance = context.Request.Path};problemDetails.Extensions.Add("traceId", context.TraceIdentifier);if (exception is ValidationException validationException){problemDetails.Extensions.Add("ValidationErrors", validationException.Errors);}await context.Response.WriteAsJsonAsync(problemDetails, cancellationToken: cancellationToken);return true;}
}
- 返回例
{"title": "ValidationException","detail": "參數驗證失敗","status": 400,"instance": "/api/products","traceId": "00-9d4a78437e-abc123def456-01","ValidationErrors": [{"PropertyName": "Name","ErrorMessage": "Name 不能為空"},{"PropertyName": "Age","ErrorMessage": "Age 必須大于 0"}]
}
1.3 注冊中間件
- 給所有微服務注冊
二、grpc服務
土耳其146
- 這里主要實現了discount模塊的grpc,我們可以通過api進行增刪改查
2.1 創建protos
1. 打折的protos
- 定義請求和返回值
syntax = "proto3";option csharp_namespace = "Discount.Grpc";package discount;// The discount service definition.
service DiscountProtoService {// Discount CRUD Operationsrpc GetDiscount (GetDiscountRequest) returns (CouponModel);rpc CreateDiscount (CreateDiscountRequest) returns (CouponModel);rpc UpdateDiscount (UpdateDiscountRequest) returns (CouponModel);rpc DeleteDiscount (DeleteDiscountRequest) returns (DeleteDiscountResponse);
}message GetDiscountRequest {string productName = 1;
}message CouponModel {int32 id = 1;string productName = 2;string description = 3;int32 amount = 4;
}message CreateDiscountRequest {CouponModel coupon = 1;
}message UpdateDiscountRequest {CouponModel coupon = 1;
}message DeleteDiscountRequest {string productName = 1;
}message DeleteDiscountResponse {bool success = 1;
}
2. 設置grpc server
- 設置grpc服務
- 設置成功后,可以在模塊的包管理器看到
3. program配置服務
4. docker-compose
2.2 CRUD
1. 查詢
2.3 測試
1. 發起查詢請求
三、grpc服務消費
土167
- Basket.Api 服務調用Discount.Grpc服務
3.1 創建client
- Basket服務要去調用Discount服務,所以Basket是 Client, Discount是 service
1. 添加服務
2. 選擇需要添加的服務類型
3. 選擇服務路徑
4. 添加成功后
- 添加成功后,basket模塊會有Protos文件夾
5. Program里添加Client服務
- 在Basket模塊的Program里添加
6. appSettings里添加grpc服務地址
- 添加Grpc的服務地址
3.2 grpc通訊
1. 在StoreBasketCommandHandler使用
- 在StoreBasketCommandHandler里進行折扣服務的扣減