Service Implementation
TheDiscountService class implements all gRPC operations defined in the discount.proto file. It inherits from the auto-generated DiscountProtoService.DiscountProtoServiceBase class.
Complete Service Code
Location:src/Services/Discount/Discount.Grpc/Services/DiscountService.cs
Service Methods
1. GetDiscount
Purpose: Retrieve discount information for a specific product. Method Signature:- Queries SQLite database using Entity Framework Core
- Returns a default “No Discount” coupon if product not found
- Logs the retrieved discount information
- Uses Mapster to map entity to gRPC model
2. CreateDiscount
Purpose: Create a new discount coupon for a product. Method Signature:CouponModel
Implementation Details:
- Validates the request - throws
RpcExceptionwithInvalidArgumentstatus if null - Uses Mapster to convert gRPC model to entity
- Adds to database and saves changes
- Returns the created coupon
3. UpdateDiscount
Purpose: Update an existing discount coupon. Method Signature:CouponModel
Implementation Details:
- Validates the incoming coupon model
- Maps gRPC model to entity
- Updates the entity in the database
- Returns the updated coupon
Update method which tracks changes and updates all properties.
4. DeleteDiscount
Purpose: Delete a discount coupon by product name. Method Signature:- Finds the coupon by product name
- Throws
RpcExceptionwithNotFoundstatus if coupon doesn’t exist - Removes from database
- Returns success response
Key Technologies
Mapster
Mapster is used for object-to-object mapping between entities and gRPC models:- Zero configuration for simple mappings
- High performance
- Compile-time safety
- Less boilerplate than manual mapping
ServerCallContext
TheServerCallContext parameter provides:
- Cancellation tokens
- Request headers and metadata
- Response trailers
- Peer information
- Deadline information
RpcException
gRPC-specific exception for communicating errors to clients:OK: SuccessCancelled: Operation cancelledInvalidArgument: Client specified invalid argumentNotFound: Requested entity not foundAlreadyExists: Entity already existsPermissionDenied: Permission deniedUnauthenticated: Authentication requiredInternal: Internal server error
Client Consumption
Adding gRPC Client (Basket Service Example)
1. Add Proto Reference (Basket.API.csproj):Service Registration
InProgram.cs, the gRPC service is registered and mapped:
Testing with gRPC Tools
Using grpcurl
List services:Logging
The service logs all operations:Best Practices Demonstrated
- Constructor Injection: Using primary constructor syntax (C# 12)
- Async/Await: All operations are asynchronous
- Graceful Degradation: GetDiscount returns default value instead of error
- Proper Error Handling: Using gRPC-specific exceptions
- Logging: Comprehensive logging of all operations
- Separation of Concerns: Entity vs gRPC model separation
- Validation: Input validation with proper error messages
Next Steps
- Protocol Buffers Definition - Detailed proto file documentation
- Overview - Service architecture and setup
