Code Monkey home page Code Monkey logo

Comments (6)

Liam-Scott-Russell avatar Liam-Scott-Russell commented on August 27, 2024 2
// just for example, not implemented yet.
builder.queryField('example', t => t.effect({
  type: '...',
  input: S.struct({
    name: S.string,
    // We have to discuss about `.pipe`. for now just keep going.
    email: S.string.pipe(...),
  })
}));
input QueryExampleInput {
  name: String
  email: String
}

I think this is the ideal outcome (mimics what the WithInput plugin does).

but effect/schema has filters as you known as .pipe method. I think this may be is very difficult point of integration. focus on defining the input types is relatively easy. but it's not worth implementing just for that. what do you think of this?

My understanding of @effect/schema is that it can:

  1. parse an arbitrary JSON object into a Schema<A>
  2. decode a Schema<A> to a different Schema<B>
  3. filter Schema<A> to Schema<A>, but some values of A might be rejected

A pipeline can apply any number of these transformations, e.g.

const customNumber: S.Schema<string, number> = pipe(
  S.string,           // parse a string: Schema<string, string>
  S.numberFromString, // decode to a number: Schema<string, number>
  S.between(1, 5),    // filter: Schema<number, number>
)

// parse from 'unknown' type
const parse = S.parse(customNumber)("some random json");
//    ^? Effect<never, ParseResult.ParseError, number>

You can do some pretty complex stuff with piping, but at the end of the day, it is still just a Schema<FromType, ToType>, so I don't think that it would be any more difficult to implement, if the standard schemas were builtin.

For example

const myType = S.struct({
    name: S.string.pipe(S.minLength(2), S.maxLength(20)),
    email: S.string.pipe(S.pattern(/emailRegex/)),
    // ^ both of these are still just Schema<string, string>
    isAdult: S.boolean,
})

const validatedBasically: unknown = {
  name: "First LastName",
  email: "[email protected]",
  isAdult: true,
}

const parsed = S.parse(myType)(validatedBasically);
//    ^? Effect<never, ParseResult.ParseError, { readonly name: string; readonly isAdult: boolean; readonly email: string; }>

What might be more difficult (as this is also going to have to generate the GraphQL schema file) is to figure out which one of the primitive GraphQL types the advanced effect types correspond to.

I have a feeling that this would be solvable using the AST module from @effect/schema/AST. If you're open to it, I'll post a draft PR this weekend demonstrating a proof of concept for compiling a Schema to a graphql type?

e.g.

S.struct({
    name: S.string.pipe(S.minLength(2), S.maxLength(20)),
    email: S.string.pipe(S.pattern(/emailRegex/)),
    isAdult: S.boolean,
})

converted into

input QueryExampleInput {
  name: String
  email: String
  isAdult: Boolean
}

from pothos-plugin-effect.

iamchanii avatar iamchanii commented on August 27, 2024

Thank you for suggestion a idea! I think graphql's basic validation and pothos's way is enough, not now, but I will considering it.

If pothos-plugin-effect would support integration with effect/schema, what should be the key point? define args or validate? I want to hear you about more context or leverage as you thought.

The following snippets are what from my imagination:

// If focused on validate:
args: {
  email: t.arg.string({
    schema: S.string.pipe(...)
  }),
},
// If focused on define args object (input type)
args: {
  email: t.arg.schema(S.string),
},
// inspired from with-input plugin
input: S.struct({
  name: S.string,
  email: S.string.pipe(...)
})

from pothos-plugin-effect.

Liam-Scott-Russell avatar Liam-Scott-Russell commented on August 27, 2024

I'm not quite sure I entirely understand the difference between defining the input types vs. validating an input type. Would using a S.schema to define an input not also validate that input? Perhaps it is because it would be difficult to do both at the same time (I'm not very familiar with the internals of pothos)?

// inspired from with-input plugin
input: S.struct({
  name: S.string,
  email: S.string.pipe(...)
})

I tend to default to the with-input style of input, i.e. a single struct as the input arguments to my resolvers, so I would definitely lean towards this option. Not saying I wouldn't use the other styles if they were implemented, but my preference is to keep it simple for the inputs.

from pothos-plugin-effect.

iamchanii avatar iamchanii commented on August 27, 2024

Good. I agree with your opinion. so if pothos-plugin-effect supports integration with effect/schema, it could define input type based on S.struct from field options in runtime. in example, the following snippet should create QueryExampleInput type.

// just for example, not implemented yet.
builder.queryField('example', t => t.effect({
  type: '...',
  input: S.struct({
    name: S.string,
    // We have to discuss about `.pipe`. for now just keep going.
    email: S.string.pipe(...),
  })
}));
input QueryExampleInput {
  name: String
  email: String
}

So far it seems to be working fine. but effect/schema has filters as you known as .pipe method. I think this may be is very difficult point of integration. focus on defining the input types is relatively easy. but it's not worth implementing just for that. what do you think of this?

(but... I think it's going to be a lot of fun!)

from pothos-plugin-effect.

iamchanii avatar iamchanii commented on August 27, 2024

@Liam-Scott-Russell Thank you for your explanation! I'm open to any kind of contribution, so I welcome you whenever you want to do it and I'll think about implementing it when I have time!

from pothos-plugin-effect.

iamchanii avatar iamchanii commented on August 27, 2024

2024 Update: I've made it clear that the role of this library is limited to handling Effect. Therefore, constructing and validating GraphQL fields or objects with Effect/Schema is beyond the goal of this library.

Thank you for your suggestion. If you have a better idea or comment, feel free to create a new issue or reopen it.

from pothos-plugin-effect.

Related Issues (18)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.