Skip to content
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

Typeorm automatically load relations when requested #33

Open
paales opened this issue Sep 6, 2019 · 2 comments
Open

Typeorm automatically load relations when requested #33

paales opened this issue Sep 6, 2019 · 2 comments
Labels
question Further information is requested

Comments

@paales
Copy link

paales commented Sep 6, 2019

Hi @capaj! Thanks for forking and extending this! I'm trying to implement GraphQL with TypeORM, so far so good, the GraphQL part is working pretty nicely, but I am not sure how I should pass the right request to Typeorm, expecially while loading relationships and relations of relations:

So I have the following Graph:
Schermafbeelding 2019-09-06 om 13 20 46

I have the following resolver:

#Schema
@SchemaRoot()
class Schema {
  @Query({ type: Voorraad })
  async inventory(artikelnummer: string, @Context { dbConn }: IContext): Promise<Voorraad> {
    const result = await dbConn.manager
      .getRepository(Voorraad)
      .findOne({ where: { artikelnummer }, relations: ['onderdeelsoort'] })
    return result
  }
}
#Relation definition
@ManyToOne(() => Ondsoort, (ondsoort: Ondsoort) => ondsoort.voorraads, {
  onDelete: 'RESTRICT',
  onUpdate: 'RESTRICT',
})
@JoinColumn({ name: 'onderdeelsoort_id' })
@Field({ type: () => Ondsoort })
onderdeelsoort: Ondsoort | null

Now I manually have to provide the relation field here, but that is far from ideal.. Can the GrapHQL request be 'automatically converted' to a TypeORM request that automatically selects the right relations and relations of relations?

@capaj
Copy link
Owner

capaj commented Sep 6, 2019

yes it can. We actually do exactly the same thing, but for objection on our @LeapLabs Looop api.
Although this functionality lies out of scope for decapi. Decapi's only job is to take arbitrary Typescript classes with methods as resolvers and generate a GQL schema.

What you need is to take TypeORM classes on input and generate decapi compatible resolvers for their relations. It would need to be developed as a separate plugin/library.
I will take a peek at it if I get some time, but no promises. I am quite busy ATM, so my delivery times are anywhere from month to half a year.

@capaj capaj added the question Further information is requested label Sep 6, 2019
@paales
Copy link
Author

paales commented Sep 6, 2019

I cobbled something together which extracts the right paths and adds them to TypeORM:

import getFieldNames from 'graphql-list-fields'

const RelationFields = Inject(({ info }) => {
  const stripDot = (path: string) =>
    path
      .split('.')
      .slice(0, path.split('.').length - 1)
      .join('.')

  let paths = getFieldNames(info).map(stripDot)

  const pathMap: Set<string> = new Set(paths.filter(_ => !!_))
  pathMap.forEach(path => pathMap.add(stripDot(path)))
  paths = [...pathMap].filter(v => !!v)

  return paths
})

async inventory(
  artikelnummer: string,
  @Context { dbConn }: IContext,
  // @ts-ignore
  @RelationFields relations,
): Promise<Voorraad> {
  return await dbConn.manager
    .getRepository(Voorraad)
    .findOne({ where: { artikelnummer }, relations })
}

The only thing I'm running into is that I can't seem to set the relations type properly? It seems that Inject always tries to return any..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants