-
Notifications
You must be signed in to change notification settings - Fork 45
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
Safe generation for create / Update InputTypes #163
Comments
There may be two other ways to solve this that require less repetition: const UserCreateInput = createInputType({ // <-- a different constructor
name: "UserCreateInput",
definition(t) {
t.field(User.id);
t.field(User.createdAt); // generates a Nullable field
t.field(User.name); // generates a NonNull field
}
}) or const UserCreateInput = inputType({
name: "UserCreateInput",
type: "create", // <-- mark as create
definition(t) {
t.field(User.id);
t.field(User.createdAt); // generates a Nullable field
t.field(User.name); // generates a NonNull field
}
}) |
@HendrikJan I dont think this is faisable. |
@lvauvillier Thanks for this proposal. This is quite interesting. So far I'm leaning toward @HendrikJan The first one should be doable somehow since its a new function that can do anything. The second one should be doable with a Prisma plugin. That said, the original proposal here seems to capture the static nature of NP right now well 🤔. |
Then I guess the original proposal will cause the least amount of headaches which sounds good to me. |
@lvauvillier I don't care about the breaking changes aspect. I'd just like to get with the best API. The reason I felt that That said I'm willing to discuss why "uniform":
Is better than "read-bias":
Pros of uniform:
Pros of read-bias
|
Food for thought: <Model>.<field>.<create | read | update> const User = objectType({
name: User.$name,
description: User.$description,
definition(t) {
t.field(User.id.read);
t.field(User.createdAt.read); // generates a NonNull field
t.field(User.name.read); // generates a NonNull field
}
}) const UserCreateInput = inputType({
name: "UserCreateInput",
definition(t) {
t.field(User.id.create);
t.field(User.createdAt.create); // generates a Nullable field
t.field(User.name.create); // generates a NonNull field
}
}) const UserUpdateInput = inputType({
name: "UserUpdateInput",
definition(t) {
t.field(User.id.update);
t.field(User.createdAt.update); // generates a Nullable field
t.field(User.name.update); // generates a Nullable field
}
}) I think my problem with this is how it reads. Also, it aligns less well from a column perspective. In a given type def the |
Hm, I think I disagree. We can have default values for both that users can opt into. For the description there can be a generic description about the operation followed by a copy of the model description. There can be a nice "title"/separation to indicate the split between those two sections. This could be a gentime settings toggle. Maybe opt-in to include the model info. It might get exhausting for API users to see that model doc over and over for every operation. const User = objectType({
name: User.$name,
description: User.$description,
definition(t) {
t.field(User.read.id);
t.field(User.read.createdAt); // generates a NonNull field
t.field(User.read.name); // generates a NonNull field
}
}) const UserCreateInput = inputType({
name: User.create.$name,
description: User.update.$description,
definition(t) {
t.field(User.create.id);
t.field(User.create.createdAt); // generates a Nullable field
t.field(User.create.name); // generates a NonNull field
}
}) const UserUpdateInput = inputType({
name: User.update.$name,
description: User.update.$description,
definition(t) {
t.field(User.update.id);
t.field(User.update.createdAt); // generates a Nullable field
t.field(User.update.name); // generates a Nullable field
}
}) |
@jasonkuhrt Interesting. We can mix the "uniform" and "read-bias" using function/args. The default create case can be expressed without any arg: const User = objectType({
name: User.$name(),
description: User.$description(),
definition(t) {
t.field(User.id());
t.field(User.createdAt()); // generates a NonNull field
t.field(User.name()); // generates a NonNull field
}
}) const UserCreateInput = inputType({
name: User.$name("create"),
description: User.$description("create"),
definition(t) {
t.field(User.id("create"));
t.field(User.createdAt("create")); // generates a Nullable field
t.field(User.name("create")); // generates a NonNull field
}
}) const UserUpdateInput = inputType({
name: User.$name("update"),
description: User.$description("update"),
definition(t) {
t.field(User.id("update"));
t.field(User.createdAt("update")); // generates a Nullable field
t.field(User.name("update")); // generates a Nullable field
}
}) |
Oh that's interesting too. I tend toward favouring static where appropriate, since more data oriented that way. I also wonder if we'd find another use-case for field parameters later (e.g. customize |
Relations will also need an entry point to inject arguments (for filtering, ordering, pagination, etc.). These are more high level abilities but we need to keep it in mind. This design can be a tradeoff between DX and extendibility. |
Perceived Problem
Currently
nexus-prisma
expose low level building blocks (field generation from prisma DMMF) to safely define Model objectTypes.Unfortunately, we can't reuse it to build safe inputTypes for create / update mutations:
For
create
inputTypes:Fields with @default value should be nullable and
resolve
function should be removedFor
update
inputTypes:All fields should be nullable and
resolve
function should be removedIdeas / Proposed Solution(s)
We can have a new api design with
read
,create
,update
:Api Design consideration:
Model.<fieldName>
) we can extend the generated model withModel.$create.<fieldName>
andModel.$update.<fieldName>
.@jasonkuhrt what do you think?
The text was updated successfully, but these errors were encountered: