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

如何修复`async_graphql::OutputType`未为`entity::user::Model`实现的错误?

解决async-graphql与SeaORM结合时OutputType未实现的问题

问题背景

在Rust项目中使用async-graphql和SeaORM编写GraphQL Mutation,尝试返回entity::user::Model类型时,出现编译错误:

the trait async_graphql::OutputType is not implemented for entity::user::Model

相关代码片段

mutation/user.rs

use crate::db::Database;
use async_graphql::*;
use chrono::Local;
use entity::user as User;
use sea_orm::{ActiveModelTrait, ActiveValue, Set};

#[derive(InputObject)]
pub struct CreateUserInput {
    pub username: String,
    // pub email: String,
}

#[derive(Default)]
pub struct UserMutation;

#[Object] // 此处报错
impl UserMutation {
    pub async fn create_user(
        &self,
        ctx: &Context<'_>,
        input: CreateUserInput,
    ) -> Result<User::Model> {
        let db = ctx.data::<Database>().unwrap();

        let user = User::ActiveModel {
            username: Set(input.username),
            created: ActiveValue::set(Local::now().naive_local()),
            updated: ActiveValue::set(Local::now().naive_local()),
            ..Default::default()
        };

        Ok(user.insert(db.get_connection()).await?)
    }
}

mutation/mod.rs

//use entity::async_graphql;

pub mod user;
pub use user::UserMutation;

#[derive(async_graphql::MergedObject, Default)]
pub struct Mutation(UserMutation);

entity/src/user.rs

use async_graphql::*;
use sea_orm::{entity::prelude::*, DeleteMany};
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize, SimpleObject)]
#[sea_orm(table_name = "users")]
#[graphql(concrete(name = "User", params()))]
pub struct Model {
    #[sea_orm(primary_key, auto_increment = true, unique)]
    #[serde(skip_deserializing)]
    pub id: i32,
    pub username: String,
    pub created: DateTime,
    pub updated: DateTime,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}

impl ActiveModelBehavior for ActiveModel {}

impl Entity {
    pub fn find_by_id(id: i32) -> Select<Entity> {
        Self::find().filter(Column::Id.eq(id))
    }

    pub fn find_by_username(title: &str) -> Select<Entity> {
        Self::find().filter(Column::Username.eq(title))
    }

    pub fn delete_by_id(id: i32) -> DeleteMany<Entity> {
        Self::delete_many().filter(Column::Id.eq(id))
    }
}

项目结构:
项目结构截图

解决步骤

1. 确认依赖特性与版本兼容性

检查Cargo.toml中的依赖配置,确保:

  • async-graphql启用了sea-orm特性
  • async-graphql与sea-orm的版本相互兼容(推荐async-graphql >=4.0,sea-orm >=0.11.0)

示例配置:

# 根项目Cargo.toml
[dependencies]
async-graphql = { version = "4.0.10", features = ["sea-orm", "chrono"] }
sea-orm = { version = "0.11.3", features = ["sqlx-mysql", "runtime-tokio-rustls", "chrono"] }

# entity子项目Cargo.toml
[dependencies]
async-graphql = { version = "4.0.10", features = ["sea-orm", "chrono"] }
sea-orm = { version = "0.11.3", features = ["sqlx-mysql", "runtime-tokio-rustls", "chrono"] }
serde = { version = "1.0", features = ["derive"] }
chrono = "0.4.24"

2. 清理冲突导入与宏配置

  • 删除mutation/mod.rs中被注释的use entity::async_graphql;,避免潜在的命名空间冲突
  • 确认entity/src/user.rs中async_graphql的导入路径正确,确保整个项目使用的是同一版本的async-graphql依赖

3. 替换返回类型为生成的GraphQL类型

在mutation/user.rs中,将返回类型从User::Model改为由#[graphql(concrete(name = "User", params()))]生成的User类型,并自动转换模型:

pub async fn create_user(
    &self,
    ctx: &Context<'_>,
    input: CreateUserInput,
) -> Result<User> {
    let db = ctx.data::<Database>().unwrap();

    let user = User::ActiveModel {
        username: Set(input.username),
        created: ActiveValue::set(Local::now().naive_local()),
        updated: ActiveValue::set(Local::now().naive_local()),
        ..Default::default()
    };

    Ok(user.insert(db.get_connection()).await?.into())
}

4. 清理编译缓存并重构

执行以下命令清除旧缓存,避免编译状态异常:

cargo clean
cargo build

验证

完成以上步骤后重新编译项目,即可解决OutputType未实现的错误,Mutation将正常返回用户模型数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 15:38:20