-
-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add InputBuilder validators & guards on fields #141
Comments
Hey I am currently learning rust, as it is a good first issue can you please assign this to me. |
@ShivangRawat30 yeah no problem. You have to extend https://github.com/SeaQL/seaography/blob/main/src/builder_context/guards.rs to support:
And apply the respective checks at
|
Hi, I'm interested in the approach to adding the InputBuilder Validators. Are there more details about how to implement it? |
Hi, I'm also interested in this feature. My current use case is skipping fields in input object types for which their corresponding SeaORM entity has a default value. For example: This is a migration that creates an use entities::*;
use sea_orm_migration::{
prelude::*,
sea_orm::{EntityTrait, Set},
};
#[derive(DeriveMigrationName)]
pub struct Migration;
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.create_table(
Table::create()
.table(Author)
.if_not_exists()
.col(
ColumnDef::new(author::Column::Id)
.uuid()
.extra("DEFAULT gen_random_uuid()")
.not_null()
.primary_key(),
)
.col(
ColumnDef::new(author::Column::Email)
.string_len(254)
.unique_key()
.not_null(),
)
.col(
ColumnDef::new(author::Column::FirstName)
.string_len(100)
.not_null(),
)
.col(
ColumnDef::new(author::Column::LastName)
.string_len(100)
.not_null(),
)
.col(
ColumnDef::new(author::Column::Username)
.string_len(50)
.unique_key()
.not_null(),
)
.col(
ColumnDef::new(post::Column::CreatedAt)
.timestamp_with_time_zone()
.extra("DEFAULT now()")
.not_null(),
)
.to_owned(),
)
.await?;
Ok(())
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(Author).to_owned())
.await?;
Ok(())
}
} here is the corresponding entity definition use sea_orm::entity::prelude::*;
use serde::Serialize;
use crate::AuthorRole;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize)]
#[sea_orm(table_name = "author")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: Uuid,
#[sea_orm(column_type = "Text", unique)]
pub email: String,
#[sea_orm(column_type = "Text")]
pub first_name: String,
#[sea_orm(column_type = "Text")]
pub last_name: String,
pub created_at: DateTimeWithTimeZone,
#[sea_orm(unique)]
pub username: String,
pub role: AuthorRole,
} Currently on type Author {
id: String!
email: String!
firstName: String!
lastName: String!
createdAt: String!
username: String!
role: AuthorRoleEnum!
post(
filters: PostFilterInput
orderBy: PostOrderInput
pagination: PaginationInput
): PostConnection!
}
type AuthorBasic {
id: String!
email: String!
firstName: String!
lastName: String!
createdAt: String!
username: String!
role: AuthorRoleEnum!
}
type AuthorConnection {
pageInfo: PageInfo!
paginationInfo: PaginationInfo
nodes: [Author!]!
edges: [AuthorEdge!]!
}
type AuthorEdge {
cursor: String!
node: Author!
}
input AuthorFilterInput {
id: TextFilterInput
email: StringFilterInput
firstName: StringFilterInput
lastName: StringFilterInput
createdAt: TextFilterInput
username: StringFilterInput
role: AuthorRoleEnumFilterInput
and: [AuthorFilterInput!]
or: [AuthorFilterInput!]
}
input AuthorInsertInput {
id: String!
email: String!
firstName: String!
lastName: String!
createdAt: String!
username: String!
role: AuthorRoleEnum!
}
input AuthorOrderInput {
id: OrderByEnum
email: OrderByEnum
firstName: OrderByEnum
lastName: OrderByEnum
createdAt: OrderByEnum
username: OrderByEnum
role: OrderByEnum
}
enum AuthorRoleEnum {
WRITTER
PUBLISHER
EDITOR
}
input AuthorRoleEnumFilterInput {
eq: AuthorRoleEnum
ne: AuthorRoleEnum
gt: AuthorRoleEnum
gte: AuthorRoleEnum
lt: AuthorRoleEnum
lte: AuthorRoleEnum
is_in: [AuthorRoleEnum!]
is_not_in: [AuthorRoleEnum!]
is_null: AuthorRoleEnum
is_not_null: AuthorRoleEnum
}
input AuthorUpdateInput {
id: String
email: String
firstName: String
lastName: String
createdAt: String
username: String
role: AuthorRoleEnum
}
input CursorInput {
cursor: String
limit: Int!
}
type Mutation {
_ping: String
authorCreateOne(data: AuthorInsertInput!): AuthorBasic!
authorCreateBatch(data: [AuthorInsertInput!]!): [AuthorBasic!]!
authorUpdate(
data: AuthorUpdateInput!
filter: AuthorFilterInput
): [AuthorBasic!]!
}
input OffsetInput {
limit: Int!
offset: Int!
}
enum OrderByEnum {
ASC
DESC
}
type PageInfo {
hasPreviousPage: Boolean!
hasNextPage: Boolean!
startCursor: String
endCursor: String
}
input PageInput {
limit: Int!
page: Int!
}
type PaginationInfo {
pages: Int!
current: Int!
offset: Int!
total: Int!
}
input PaginationInput {
cursor: CursorInput
page: PageInput
offset: OffsetInput
}
type Query {
author(
filters: AuthorFilterInput
orderBy: AuthorOrderInput
pagination: PaginationInput
): AuthorConnection!
}
input StringFilterInput {
eq: String
ne: String
gt: String
gte: String
lt: String
lte: String
is_in: [String!]
is_not_in: [String!]
is_null: String
is_not_null: String
contains: String
starts_with: String
ends_with: String
like: String
not_like: String
between: [String!]
not_between: [String!]
}
input TextFilterInput {
eq: String
ne: String
gt: String
gte: String
lt: String
lte: String
is_in: [String!]
is_not_in: [String!]
is_null: String
is_not_null: String
between: [String!]
not_between: [String!]
} Ideally I think that the behavior should be that the fields that have default values don't need to be optionally in the Rust entity but should not be included in the |
I found that if I modify how the lazy_static::lazy_static! {
static ref CONTEXT : BuilderContext = {
let mut context = BuilderContext::default();
context.entity_input.insert_skips.push("Author.id".into());
context.entity_input.insert_skips.push("Author.role".into());
context.entity_input.insert_skips.push("Author.createdAt".into());
context
};
} What would the proper way of initializing the |
The problem I see is that for some fields I would like to exclude them from the insert and update input like |
Hello @YiNNx and thanks for your interest. So far the supported mutations are create and update and I hope to release the delete soon. If you read the comment I created a while ago it provides a file from where to start. The guards file currently has guards for query and query filter options. If you search those on code you can find more about how this feature works. We just need to further expand it for mutations. I will look it up and add more info on this issue later. |
Thanks for your comments @guidomb. Could you open a separate issue so we can address this separately? |
Motivation
When creating, updating or deleting and item you can access all fields and properties. There should be a way to limit this by applying policy rules.
Proposed Solutions
Extend the input module to allow the configuration of validators and guards to be associated with entity input fields.
Additional Information
See guards on entities output fields
The text was updated successfully, but these errors were encountered: