You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在gRPC微服务架构下集成Django与Spring Boot并实现CRUD操作?

解决方案:Django + Spring Boot(gRPC) + MongoDB 集成实现CRUD

1. 定义gRPC协议(通信契约)

先编写.proto文件,明确实体结构和CRUD服务接口,这是两端交互的核心标准。以User实体为例:

syntax = "proto3";

package user;

// 用户实体结构
message User {
  string id = 1;
  string name = 2;
  string email = 3;
  int32 age = 4;
}

// 创建用户请求
message CreateUserRequest {
  string name = 1;
  string email = 2;
  int32 age = 3;
}

// 查询单个用户请求
message GetUserRequest {
  string id = 1;
}

// 更新用户请求
message UpdateUserRequest {
  string id = 1;
  string name = 2;
  string email = 3;
  int32 age = 4;
}

// 删除用户请求
message DeleteUserRequest {
  string id = 1;
}

// 通用响应格式
message CommonResponse {
  bool success = 1;
  string message = 2;
}

// gRPC服务接口定义
service UserService {
  rpc createUser(CreateUserRequest) returns (User);
  rpc getUser(GetUserRequest) returns (User);
  rpc updateUser(UpdateUserRequest) returns (User);
  rpc deleteUser(DeleteUserRequest) returns (CommonResponse);
}

2. Spring Boot 端实现gRPC服务(操作MongoDB)

2.1 引入依赖

在pom.xml中添加gRPC和Spring Data MongoDB依赖:

<!-- gRPC Spring Boot Starter -->
<dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-server-spring-boot-starter</artifactId>
    <version>2.15.0.RELEASE</version>
</dependency>
<!-- Spring Data MongoDB -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

2.2 生成Java代码

添加Maven插件自动生成proto对应的Java类,在pom.xml的build节点下插入:

<extensions>
    <extension>
        <groupId>kr.motd.maven</groupId>
        <artifactId>os-maven-plugin</artifactId>
        <version>1.7.0</version>
    </extension>
</extensions>
<plugins>
    <plugin>
        <groupId>org.xolstice.maven.plugins</groupId>
        <artifactId>protobuf-maven-plugin</artifactId>
        <version>0.6.1</version>
        <configuration>
            <protocArtifact>com.google.protobuf:protoc:3.21.7:exe:${os.detected.classifier}</protocArtifact>
            <pluginId>grpc-java</pluginId>
            <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.51.0:exe:${os.detected.classifier}</pluginArtifact>
        </configuration>
        <executions>
            <execution>
                <goals>
                    <goal>compile</goal>
                    <goal>compile-custom</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>

执行mvn compile即可生成对应Java代码。

2.3 实现MongoDB实体与Repository

创建MongoDB映射实体:

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "users")
public class UserEntity {
    @Id
    private String id;
    private String name;
    private String email;
    private int age;

    // 构造函数、getter、setter
}

编写Repository接口:

import org.springframework.data.mongodb.repository.MongoRepository;

public interface UserRepository extends MongoRepository<UserEntity, String> {
}

2.4 实现gRPC服务类

继承自动生成的UserServiceGrpc.UserServiceImplBase,实现CRUD逻辑:

import net.devh.boot.grpc.server.service.GrpcService;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
import org.springframework.beans.factory.annotation.Autowired;

@GrpcService
public class UserGrpcService extends UserServiceGrpc.UserServiceImplBase {

    @Autowired
    private UserRepository userRepository;

    @Override
    public void createUser(CreateUserRequest request, StreamObserver<User> responseObserver) {
        UserEntity entity = new UserEntity();
        entity.setName(request.getName());
        entity.setEmail(request.getEmail());
        entity.setAge(request.getAge());
        UserEntity saved = userRepository.save(entity);
        
        User user = User.newBuilder()
                .setId(saved.getId())
                .setName(saved.getName())
                .setEmail(saved.getEmail())
                .setAge(saved.getAge())
                .build();
        responseObserver.onNext(user);
        responseObserver.onCompleted();
    }

    @Override
    public void getUser(GetUserRequest request, StreamObserver<User> responseObserver) {
        userRepository.findById(request.getId())
                .ifPresentOrElse(entity -> {
                    User user = User.newBuilder()
                            .setId(entity.getId())
                            .setName(entity.getName())
                            .setEmail(entity.getEmail())
                            .setAge(entity.getAge())
                            .build();
                    responseObserver.onNext(user);
                    responseObserver.onCompleted();
                }, () -> {
                    responseObserver.onError(new StatusRuntimeException(Status.NOT_FOUND));
                });
    }

    @Override
    public void updateUser(UpdateUserRequest request, StreamObserver<User> responseObserver) {
        userRepository.findById(request.getId())
                .ifPresentOrElse(entity -> {
                    entity.setName(request.getName());
                    entity.setEmail(request.getEmail());
                    entity.setAge(request.getAge());
                    UserEntity updated = userRepository.save(entity);
                    User user = User.newBuilder()
                            .setId(updated.getId())
                            .setName(updated.getName())
                            .setEmail(updated.getEmail())
                            .setAge(updated.getAge())
                            .build();
                    responseObserver.onNext(user);
                    responseObserver.onCompleted();
                }, () -> {
                    responseObserver.onError(new StatusRuntimeException(Status.NOT_FOUND));
                });
    }

    @Override
    public void deleteUser(DeleteUserRequest request, StreamObserver<CommonResponse> responseObserver) {
        userRepository.findById(request.getId())
                .ifPresentOrElse(entity -> {
                    userRepository.delete(entity);
                    CommonResponse response = CommonResponse.newBuilder()
                            .setSuccess(true)
                            .setMessage("User deleted successfully")
                            .build();
                    responseObserver.onNext(response);
                    responseObserver.onCompleted();
                }, () -> {
                    CommonResponse response = CommonResponse.newBuilder()
                            .setSuccess(false)
                            .setMessage("User not found")
                            .build();
                    responseObserver.onNext(response);
                    responseObserver.onCompleted();
                });
    }
}

2.5 配置服务参数

在application.properties中设置gRPC端口和MongoDB连接:

grpc.server.port=9090
spring.data.mongodb.uri=mongodb://localhost:27017/your_database_name

3. Django 端集成gRPC客户端

3.1 安装依赖

通过pip安装gRPC相关包:

pip install grpcio grpcio-tools

3.2 生成Python代码

将.proto文件放到Django项目的proto目录下,执行命令生成Python代码:

python -m grpc_tools.protoc -I./proto --python_out=./your_django_app --grpc_python_out=./your_django_app ./proto/user.proto

执行后会生成user_pb2.py和user_pb2_grpc.py两个文件。

3.3 封装gRPC客户端工具

在Django app中编写工具类,简化gRPC调用:

import grpc
import user_pb2
import user_pb2_grpc

GRPC_SERVER_ADDRESS = 'localhost:9090'

def get_user_stub():
    channel = grpc.insecure_channel(GRPC_SERVER_ADDRESS)
    return user_pb2_grpc.UserServiceStub(channel)

# 创建用户
def create_user(name, email, age):
    stub = get_user_stub()
    request = user_pb2.CreateUserRequest(name=name, email=email, age=age)
    return stub.createUser(request)

# 查询用户
def get_user(user_id):
    stub = get_user_stub()
    request = user_pb2.GetUserRequest(id=user_id)
    try:
        return stub.getUser(request)
    except grpc.RpcError as e:
        if e.code() == grpc.StatusCode.NOT_FOUND:
            return None
        raise

# 更新用户
def update_user(user_id, name, email, age):
    stub = get_user_stub()
    request = user_pb2.UpdateUserRequest(id=user_id, name=name, email=email, age=age)
    try:
        return stub.updateUser(request)
    except grpc.RpcError as e:
        if e.code() == grpc.StatusCode.NOT_FOUND:
            return None
        raise

# 删除用户
def delete_user(user_id):
    stub = get_user_stub()
    request = user_pb2.DeleteUserRequest(id=user_id)
    return stub.deleteUser(request)

3.4 编写Django视图处理HTTP请求

编写视图函数映射HTTP请求到gRPC调用:

from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
import json
from .grpc_client import create_user, get_user, update_user, delete_user

@require_http_methods(["POST"])
def create_user_view(request):
    data = json.loads(request.body)
    try:
        user = create_user(data['name'], data['email'], data['age'])
        return JsonResponse({
            'id': user.id,
            'name': user.name,
            'email': user.email,
            'age': user.age
        }, status=201)
    except Exception as e:
        return JsonResponse({'error': str(e)}, status=500)

@require_http_methods(["GET"])
def get_user_view(request, user_id):
    user = get_user(user_id)
    if not user:
        return JsonResponse({'error': 'User not found'}, status=404)
    return JsonResponse({
        'id': user.id,
        'name': user.name,
        'email': user.email,
        'age': user.age
    })

@require_http_methods(["PUT"])
def update_user_view(request, user_id):
    data = json.loads(request.body)
    user = update_user(user_id, data['name'], data['email'], data['age'])
    if not user:
        return JsonResponse({'error': 'User not found'}, status=404)
    return JsonResponse({
        'id': user.id,
        'name': user.name,
        'email': user.email,
        'age': user.age
    })

@require_http_methods(["DELETE"])
def delete_user_view(request, user_id):
    response = delete_user(user_id)
    return JsonResponse({
        'success': response.success,
        'message': response.message
    }, status=200 if response.success else 404)

3.5 配置URL路由

在urls.py中添加路由映射:

from django.urls import path
from .views import create_user_view, get_user_view, update_user_view, delete_user_view

urlpatterns = [
    path('users/', create_user_view, name='create_user'),
    path('users/<str:user_id>/', get_user_view, name='get_user'),
    path('users/<str:user_id>/update/', update_user_view, name='update_user'),
    path('users/<str:user_id>/delete/', delete_user_view, name='delete_user'),
]

4. 验证流程

  1. 启动MongoDB服务
  2. 启动Spring Boot应用,确保gRPC服务在9090端口正常运行
  3. 启动Django开发服务器
  4. 用curl或Postman测试各接口:
    • POST /users/ 创建用户
    • GET /users/{id}/ 查询用户
    • PUT /users/{id}/update/ 更新用户
    • DELETE /users/{id}/delete/ 删除用户

内容的提问来源于stack exchange,提问作者Asanabada Bhavesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 10:06:44