polywrap / wrap-cli

Used to create, build, and integrate wraps.
https://polywrap.io
MIT License
170 stars 52 forks source link

Interfaces & getImplementations Refactor #547

Open dOrgJelli opened 3 years ago

dOrgJelli commented 3 years ago

In the PR that was recently merged here: https://github.com/polywrap/monorepo/pull/534

We decided as a team to "move fast" and implement a few things that are not ideal. Additionally there are things that are currently allowed, but should not. These things are:

  1. @enabled_interface directive, which tells the code generation logic that an imported Query type is (1) an interface and (2) can be queried using a user-defined URI at run-time. This directive's usage pattern & naming is confusing and can be done in a more "understandable" way.
  2. isInterface property on ImportedQueryDefinitions.
  3. Users can use any type as an interface using the GraphQL keyword implements. This should be restricted to interface types only.
  4. The concept of capabilities using the #use { ... } on ... syntax may not be necessary. Alternatively, we could turn getImplementations and customImplementation into capabilities. These two things are "nice to know" if your client runtime wants to do things like (1) restrict the querying of implementations, or (2) restrict the querying of custom implementations that aren't "registered" / "pre-known".
  5. Interfaces are not properly implemented in the bindings. Types that implement interfaces do not have the inheritance represented in the bindings.

A proposed refactor, that would make this all a bit more future proofed (in the medium term), would be:

  1. Inside of all "interface" packages (i.e. a wrapper w/o any Wasm implementation, just schema), we should add this directive to all schema types defined:
    
    directive @interface on OBJECT

type Mutation @interface { abstractMutationMethod( arg: String! ): UInt8! }

type CustomObj @interface { prop: String! }

2. Only allow users to `implements` within GraphQL using `@interface` types.
3. Make sure the bindings represent the interface inheritance (multiple interfaces as well).
4. only allow `getImplementations` on interface URIs.
5. Update the TypeInfo structure to look something like this:
```typescript
interface NewTypeInfo {
  objectTypes: ObjectDefinition[];
  queryTypes: QueryDefinition[];
  enumTypes: EnumDefinition[];

  dependencies: {
    namespace: {
      uri: string;
      name: string;
      type: "wrapper" | "interface" | "plugin";
      capabilities: CapabilityDefinition;
    };
    objectTypes: ImportedObjectDefinition[];
    queryTypes: ImportedQueryDefinition[];
    enumTypes: ImportedEnumDefinition[];
  }[];
}
dOrgJelli commented 3 years ago

A longer term refactor is being spec'd out here: https://github.com/dOrgJelli/wrap-abi-brainstorming