357 lines
5.6 KiB
Markdown
357 lines
5.6 KiB
Markdown
# 🚀 EonaCat.gRPC
|
|
|
|
A modern .NET 10 gRPC solution built with:
|
|
|
|
* ✅ Code-First gRPC using ProtoBuf.Grpc
|
|
* ✅ Dependency Injection
|
|
* ✅ JWT Authentication
|
|
* ✅ Entity Framework Core
|
|
* ✅ JSON Transcoding (REST ↔ gRPC)
|
|
* ✅ Swagger/OpenAPI Support
|
|
* ✅ Request/Response Interceptors
|
|
* ✅ Structured Logging with EonaCat.LogStack
|
|
* ✅ Clean Architecture Separation
|
|
|
|
---
|
|
|
|
# Features
|
|
|
|
* High-performance gRPC services
|
|
* HTTP/JSON endpoint support through gRPC transcoding
|
|
* JWT authentication and authorization
|
|
* Automatic Swagger documentation
|
|
* Request tracing and exception handling
|
|
* Repository pattern implementation
|
|
* Service layer abstraction
|
|
* Dependency Injection support throughout the application
|
|
|
|
---
|
|
|
|
# Project Structure
|
|
|
|
```text
|
|
EonaCat.gRPC.Api
|
|
│
|
|
├── EonaCat.gRPC.Api → ASP.NET Core gRPC Host
|
|
├── EonaCat.gRPC.Service → Business Logic
|
|
├── EonaCat.gRPC.Core → Domain Models & Interfaces
|
|
├── EonaCat.gRPC.Repository → Data Access Layer
|
|
├── EonaCat.gRPC.Proto → gRPC Contracts
|
|
└── EonaCat.gRPC.Client → Sample Client
|
|
```
|
|
|
|
---
|
|
|
|
# Requirements
|
|
|
|
* .NET 10 SDK
|
|
* SQL Server
|
|
* Visual Studio 2022+ or Rider
|
|
|
|
# Installation
|
|
|
|
Clone the repository:
|
|
|
|
```bash
|
|
git clone https://github.com/your-org/EonaCat.gRPC.git
|
|
cd EonaCat.gRPC
|
|
```
|
|
|
|
Restore packages:
|
|
|
|
```bash
|
|
dotnet restore
|
|
```
|
|
|
|
Build:
|
|
|
|
```bash
|
|
dotnet build
|
|
```
|
|
|
|
Run API:
|
|
|
|
```bash
|
|
dotnet run --project EonaCat.gRPC.Api
|
|
```
|
|
|
|
# Configuration
|
|
|
|
## appsettings.json
|
|
|
|
```json
|
|
{
|
|
"ConnectionStrings": {
|
|
"DefaultConnection": "Server=.;Database=GrpcDb;Trusted_Connection=True;"
|
|
},
|
|
|
|
"Jwt": {
|
|
"Secret": "your-super-secret-key"
|
|
}
|
|
}
|
|
```
|
|
|
|
# Dependency Injection
|
|
|
|
Services are registered automatically during startup.
|
|
|
|
```csharp
|
|
builder.Services.AddTransient<IUserService, UserService>();
|
|
|
|
builder.Services.AddScoped<IUserRepository, UserRepository>();
|
|
|
|
builder.Services.AddScoped(typeof(IBaseRepository<>),
|
|
typeof(BaseRepository<>));
|
|
```
|
|
|
|
# gRPC Service Registration
|
|
|
|
```csharp
|
|
builder.Services.AddGrpc(options =>
|
|
{
|
|
options.Interceptors.Add<LoggerInterceptor>();
|
|
options.Interceptors.Add<ExceptionInterceptor>();
|
|
});
|
|
|
|
builder.Services.AddCodeFirstGrpc();
|
|
builder.Services.AddGrpcReflection();
|
|
builder.Services.AddGrpcSwagger();
|
|
builder.Services.AddGrpc().AddJsonTranscoding();
|
|
```
|
|
|
|
# User Service Contract
|
|
|
|
```csharp
|
|
[ServiceContract]
|
|
public interface IProtoUserService
|
|
{
|
|
ValueTask<BaseResponse<string>> Create(
|
|
UserCreateRequest request);
|
|
|
|
Task<BaseResponse<UserResponse?>> GetByIdAsync(
|
|
string id);
|
|
|
|
Task<BaseResponse<List<UserResponse>?>> GetAsync();
|
|
}
|
|
```
|
|
|
|
# Creating a User
|
|
|
|
## Request
|
|
|
|
```csharp
|
|
var request = new UserCreateRequest
|
|
{
|
|
FirstName = "John",
|
|
LastName = "Doe",
|
|
Email = "john@example.com"
|
|
};
|
|
```
|
|
|
|
## Client Call
|
|
|
|
```csharp
|
|
var response = await client.Create(request);
|
|
|
|
Console.WriteLine(response.Data);
|
|
```
|
|
|
|
# Getting a User
|
|
|
|
```csharp
|
|
var response = await client.GetByIdAsync("1");
|
|
|
|
Console.WriteLine(response.Data?.FirstName);
|
|
```
|
|
|
|
# Getting All Users
|
|
|
|
```csharp
|
|
var users = await client.GetAsync();
|
|
|
|
foreach (var user in users.Data)
|
|
{
|
|
Console.WriteLine(user.Email);
|
|
}
|
|
```
|
|
|
|
# Client Example
|
|
|
|
```csharp
|
|
using Grpc.Net.Client;
|
|
|
|
using var channel =
|
|
GrpcChannel.ForAddress("http://localhost:5227");
|
|
|
|
var client =
|
|
channel.CreateGrpcService<IProtoUserService>();
|
|
|
|
var users = await client.GetAsync();
|
|
```
|
|
|
|
# JSON Transcoding
|
|
|
|
Because JSON Transcoding is enabled, services can be accessed through standard HTTP requests.
|
|
|
|
Example:
|
|
|
|
```http
|
|
GET /users
|
|
```
|
|
|
|
```http
|
|
GET /users/1
|
|
```
|
|
|
|
This allows browsers, Postman, mobile apps, and JavaScript applications to consume your gRPC services.
|
|
|
|
# Authentication
|
|
|
|
JWT Authentication is configured using:
|
|
|
|
```csharp
|
|
builder.Services
|
|
.AddAuthentication()
|
|
.AddJwtBearer(options =>
|
|
{
|
|
options.TokenValidationParameters =
|
|
new TokenValidationParameters
|
|
{
|
|
ValidateIssuerSigningKey = true
|
|
};
|
|
});
|
|
```
|
|
|
|
Add your token:
|
|
|
|
```http
|
|
Authorization: Bearer YOUR_TOKEN
|
|
```
|
|
|
|
# Logging
|
|
|
|
EonaCat.LogStack is integrated throughout the solution.
|
|
|
|
```csharp
|
|
builder.AddEonaCatLogging();
|
|
```
|
|
|
|
Client logging:
|
|
|
|
```csharp
|
|
LoggerFactory.Create(builder =>
|
|
{
|
|
builder.AddEonaCatLogging();
|
|
builder.SetMinimumLevel(LogLevel.Debug);
|
|
});
|
|
```
|
|
|
|
# Interceptors
|
|
|
|
## Logging Interceptor
|
|
|
|
```csharp
|
|
options.Interceptors.Add<LoggerInterceptor>();
|
|
```
|
|
|
|
Provides:
|
|
|
|
* Request logging
|
|
* Response logging
|
|
* Execution timing
|
|
* Diagnostics
|
|
|
|
## Exception Interceptor
|
|
|
|
```csharp
|
|
options.Interceptors.Add<ExceptionInterceptor>();
|
|
```
|
|
|
|
Provides:
|
|
|
|
* Global exception handling
|
|
* Consistent error responses
|
|
* Centralized logging
|
|
|
|
# Swagger Support
|
|
|
|
Swagger UI is automatically enabled.
|
|
|
|
Navigate to:
|
|
|
|
```text
|
|
https://localhost:<port>/swagger
|
|
```
|
|
|
|
You can:
|
|
|
|
* Browse endpoints
|
|
* Test requests
|
|
* Inspect schemas
|
|
* View authentication requirements
|
|
|
|
# Reflection Support
|
|
|
|
Reflection is enabled for tools such as:
|
|
|
|
* grpcurl
|
|
* Postman
|
|
* BloomRPC
|
|
* Kreya
|
|
|
|
```csharp
|
|
app.MapGrpcReflectionService();
|
|
```
|
|
|
|
# Example grpcurl Commands
|
|
|
|
List services:
|
|
|
|
```bash
|
|
grpcurl localhost:5227 list
|
|
```
|
|
|
|
Describe service:
|
|
|
|
```bash
|
|
grpcurl localhost:5227 describe IProtoUserService
|
|
```
|
|
|
|
Call endpoint:
|
|
|
|
```bash
|
|
grpcurl \
|
|
-d '{"id":"1"}' \
|
|
localhost:5227 \
|
|
IProtoUserService/GetByIdAsync
|
|
```
|
|
|
|
---
|
|
|
|
# Architecture
|
|
|
|
```text
|
|
Client
|
|
│
|
|
▼
|
|
gRPC API
|
|
│
|
|
▼
|
|
Service Layer
|
|
│
|
|
▼
|
|
Repository Layer
|
|
│
|
|
▼
|
|
SQL Server
|
|
```
|
|
|
|
# Performance Benefits
|
|
|
|
Compared to traditional REST APIs:
|
|
|
|
* Smaller payloads
|
|
* Faster serialization
|
|
* HTTP/2 support
|
|
* Strongly typed contracts
|
|
* Better streaming capabilities |