comigor / artemis

Build dart types from GraphQL schemas and queries
MIT License
496 stars 119 forks source link

Possible to generate schema types? #39

Open micimize opened 4 years ago

micimize commented 4 years ago

Is there a way to generate classes from the base types of a schema? Is this planned?

We'll want to do this for graphql-flutter, and maintain fragment inheritance somehow

Maybe something like this: https://gist.github.com/micimize/ec9df3c1df23f415621fd3da7e81209e ```dart // base type class Foo { String _foo; int _bar; } //fragment exposing foo class FooFragment extends Foo { String get foo => _foo; set foo(String value) => _foo = value; FooFragment({String foo}) { this.foo = foo; } } ```

Relatedly, we'll need to be able to customize the generated models if we continue with the moor cache route

comigor commented 4 years ago

Hello @micimize, how you doing?

Is there a way to generate classes from the base types of a schema? Is this planned?

You mean generate all types from all the schema, instead of filtering by queries/mutations fragments? That's actually what Artemis used to do before v0.2.0, but I felt it was really not useful, so I've dropped it in favor of fields needed by the query alone.

I'm not familiar with MoorDB, could you explain your use case?

About fragment inheritance & full schema typing, are you talking about having generated classes for the whole schema and queries fragments using them just like your example? How would you deal with non-nullables (I know Artemis can't handle it yet, but I'm asking for future references)?

Relatedly, we'll need to be able to customize the generated models if we continue with the moor cache route

I was already thinking about somehow exposing the class generation given data classes, allowing custom interceptors/parsers on the generator, defaulting to the current one. Do you think that should be enough to your use case?

micimize commented 4 years ago

You mean generate all types from all the schema, instead of filtering by queries/mutations fragments?

Exactly. Moor is an sqllite lib we're considering building a normalized cache with. So, we'd want to generate a table model per base-type, and normalize operation results into the cache.

are you talking about having generated classes for the whole schema and queries fragments using them just like your example?

Yes - this would let us inherit from the database-connected types, and allow for fragment-like Inheritance.

For non-nullables, I don't think it changes anything, we can just use a non-nullable decorator on deserialization

On generator customization - that's pretty close, we'd need to be able to define property getters though. An example moor generation:

# in
type TodoEntry {
  id: Int!
  content: String!
  targetDate: Datetime
}
// out
@DataClassName('TodoEntry')
class TodoEntryTable extends Table {
  IntColumn get id => integer()();

  TextColumn get content => text()();

  DateTimeColumn get targetDate => dateTime().nullable()();
}

I think we could collect class names for the database definition itself with OnNewClassFoundCallback.

comigor commented 4 years ago

So you're developing another generator (for Moor) that uses Artemis? Could you point me to the repo?

Are you depending on it as a library or as a build dependency? GraphQLQueryBuilder currently implements a callback of parsed data which I primarily use for testing, but I think you can use instead of OnNewClassFoundCallback, making it easier to generate your own classes after Artemis parsing.

But yeah, we still need to upgrade Artemis to (optionally) generate the full schema.

micimize commented 4 years ago

@comigor it's still in the consideration/planning phase - we haven't begun development yet.

comigor commented 4 years ago

I see. Well, ping me if you try OnBuildQuery/OnNewClassFoundCallback. I'll see if it's easy to generate the whole schema again.

Just two cents from someone who doesn't fully understand MoorDB/graphql-flutter ecosystem, if you're open to this feedback Implement this cache as an optional & pluggable dependency (even if it's the most recommended cache implementation), instead of having it on the same package. The current implemented caches have a hard dependency to `path_provider`, which makes usage on flutter web more difficult, for instance. IMO everything should be as pure as possible.