How to integrate Neo4j database, NestJS framework and GraphQL?

匆匆过客 提交于 2019-12-13 07:53:58

问题


I'm trying to integrate my REST API (NestJS) with new Neo4j database with GraphQL queries. Anybody succeed? Thanks in advance

EDIT 1: (I added my code)

import { Resolver } from "@nestjs/graphql";
import { Query, forwardRef, Inject, Logger } from "@nestjs/common";
import { Neo4jService } from "src/shared/neo4j/neoj4.service";
import { GraphModelService } from "./models/model.service";
import { Movie } from "src/graphql.schema";

@Resolver('Movie')
    export class GraphService {
    constructor(private readonly _neo4jService: Neo4jService) {}

    @Query()
    async getMovie() {
        console.log("hello");
        return neo4jgraphql(/*i don't know how get the query and params*/);
    }
}

回答1:


I am using a NestInterceptor to accomplish this:

@Injectable()
export class Neo4JGraphQLInterceptor implements NestInterceptor {
  intercept(
    context: ExecutionContext,
    next: CallHandler<any>,
  ): Observable<any> | Promise<Observable<any>> {
    const ctx = GqlExecutionContext.create(context);
    return neo4jgraphql(
      ctx.getRoot(),
      ctx.getArgs(),
      ctx.getContext(),
      ctx.getInfo(),
    );
  }
}

To use it in your Resolver:

@Resolver('Movie')
@UseInterceptors(Neo4JGraphQLInterceptor)
export class MovieResolver {}

My GraphQLModule is configured like this:

@Module({
  imports: [
    GraphQLModule.forRoot({
      typePaths: ['./**/*.gql'],
      transformSchema: augmentSchema,
      context: {
        driver: neo4j.driver(
          'bolt://neo:7687',
          neo4j.auth.basic('neo4j', 'password1234'),
        ),
      },
    }),
  ],
  controllers: [...],
  providers: [..., MovieResolver, Neo4JGraphQLInterceptor],
})

Note the usage of transformSchema: augmentSchema to enable auto-generated mutations and queries (GRANDStack: Schema Augmentation)

Hope that helps a bit!




回答2:


I have not worked on GraphQL, but I know there is a npm package(Neo4j-graphql-js) to translate GraphQL queries into Cypher queries. It makes easier to use GraphQL and Neo4j together.

Also, check GRANDstack it is a full-stack development integration for building Graph-based applications.

If you ask these type of questions here you will downvote only, I suggest you visit Neo4j Community.




回答3:


This is what works for me...not as elegant as I would like but it works; I want to have only one service/provider accessing my db not the service from each module even though that works also. So I am sticking with the Nest format of myModule->myResolver->myService-->Neo4jService. So Neo4jService is injected in all xService(s). I am using neo4jGraphql and augmentSchema and Cypher when necessary.

Code:

**appmodule.ts**
....
import { makeExecutableSchema } from 'graphql-tools';
import { v1 as neo4j } from 'neo4j-driver';
import { augmentTypeDefs, augmentSchema  } from 'neo4j-graphql-js';
import { Neo4jService } from './neo4j/neo4j.service';
import { MyModule } from './my/my.module';
import { MyResolver } from './my/my.resolver';
import { MyService } from './my/my.service';
....
import { typeDefs } from './generate-schema';  // SDL type file
...
const driver =  neo4j.driver('bolt://localhost:3000', neo4j.auth.basic('neo4j', 'neo4j'))

const schema = makeExecutableSchema({
  typeDefs: augmentTypeDefs(typeDefs),
 });
const augmentedSchema = augmentSchema(schema);   // Now we have an augmented schema

@Module({
  imports: [
    MyModule,

    GraphQLModule.forRoot({
      schema: augmentedSchema,       
      context: {
      driver,
       },
     }),
    ],
  controllers: [],

  providers: [ Neo4jService,
               myResolver,
             ],
})
export class AppModule {}

**myResolver.ts**

import { Args, Mutation, Query, Resolver  } from '@nestjs/graphql';

import { MyService } from './my.service';

@Resolver('My')
export class MyResolver {

    constructor(
        private readonly myService: MyService) {}

      @Query()
      async getData(object, params, ctx, resolveInfo) {
       return await this.myService.getData(object, params, ctx, resolveInfo);
      }

     *//Notice I am just passing the graphql params, etc to the myService*

}

**myService.ts**

import { Injectable } from '@nestjs/common';
import { Neo4jService } from '../neo4j/neo4j.service';

@Injectable()
export class MyService {

    constructor(private neo4jService: Neo4jService) {}

    async getData(object, params, ctx, resolveInfo) {
        return await this.neo4jService.getData(object, params, ctx, resolveInfo);
   }

     *// Again I am just passing the graphql params, etc to the neo4jService*
 }
**neo4jService.ts**
import { Injectable } from '@nestjs/common';
import { neo4jgraphql } from 'neo4j-graphql-js';


@Injectable()
export class Neo4jService {

        getData(object, params, ctx, resolveInfo) {
              return neo4jgraphql(object, params, ctx, resolveInfo);
            }
     .....
     ......
}

So basically I postponed using neo4jgraphql until we arrive at neo4jService. Now all my DB calls are here.....as I said not elegant but it works.

Challenges: Graphql generate would not accept @relation...I found out that a change was made and now you need augmentTypeDefs. ...hope this helps EDIT Nestjs takes an awful long time to process the augmentSchema...so I would recommend skipping it..for now




回答4:


Here is an example i created for (NestJS + GraphQL + Neo4j). I hope if this may help!

NestJS + GraphQL + Neo4j



来源:https://stackoverflow.com/questions/53544876/how-to-integrate-neo4j-database-nestjs-framework-and-graphql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!