Skip to content

Inherit types #189

Open
Open
@dwwoelfel

Description

I'm working on implementing a Node interface for OneGraph. Each of our underlying APIs implements its own node interface, so we have GitHubNode, SalesforceNode, IntercomNode, etc.

To implement the resolver for the OneGraphNode, I just need to determine which service the nodeId is for, then utilize the existing machinery for resolving a node.

It would look something like:

field(
  "node",
  ~args=Arg.[arg("oneGraphId", ~typ=non_null(guid))],
  ~typ=oneGraphNodeInterface,
  ~resolve=(resolveInfo, (), id) =>
  switch (decodeNodeId(id)) {
  | Ok({service, serviceNodeId}) =>
    switch (service) {
    | `GitHub => resolveGitHubNode(serviceNodeId) |> gitHubNodeToOneGraphNode
    | `Salesforce => resolveSalesforceNode(serviceNodeId) |> salesforceNodeToOneGraphNode
    }
  }
);

It would be really handy if I had a way to convert from the underlying service's node interface to the OneGraph node interface.

Would you be open to a new inherit_types function that copied all the types from one interface to another and created a function to coerce from one interface to another?

It would look like:

  let inherit_types :
    'a 'b.
    ('ctx, 'a) abstract_typ ->
    ('ctx, 'b) abstract_typ ->
    ('ctx, 'a) abstract_value -> ('ctx, 'b) abstract_value =
    fun from_abstract_typ to_abstract_typ ->
    match (from_abstract_typ, to_abstract_typ) with
    | (Abstract from_typ), (Abstract to_typ) ->
       to_typ.types <- List.concat [from_typ.types; to_typ.types];
       List.iter (fun o ->
                  match o with
                  | AnyTyp (Object o) -> o.abstracts := to_typ :: !(o.abstracts)
                  | _ -> invalid_arg "Types for Abstract type must be objects"
                 ) to_typ.types;
       fun (AbstractValue (from_typ, src)) -> (AbstractValue (from_typ, src))
    | _ -> invalid_arg "Arguments must both be Interface/Union"

With that function, I could easily construct gitHubNodeToOneGraphNode and salesforceNodeToOneGraphNode above by doing:

let gitHubNodeToOneGraphNode = Schema.inherit_types(gitHubNode, oneGraphNodeInterface);
let salesforceNodeToOneGraphNode = Schema.inherit_types(salesforceNode, oneGraphNodeInterface);

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions