Initial version
This commit is contained in:
@@ -1,3 +1,357 @@
|
||||
# EonaCat.gRPC
|
||||
# 🚀 EonaCat.gRPC
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user