问题
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