简体   繁体   中英

What is the difference of resolver/service in nestJS using graphql?

I do not understand the difference between a resolver and a service in a nestJS application using graphQl and mongoDB.

I found examples like this, where the resolver just calls a service, so the resolver functions are always small as they just call a service function. But with this usage I don't understand the purpose of the resolver at all...

@Resolver('Tasks')
export class TasksResolver {
  constructor(
    private readonly taskService: TasksService
  ) {}

  @Mutation(type => WriteResult)
  async deleteTask(
    @Args('id') id: string,
  ) {
    return this.taskService.deleteTask(id);
  }
}


@Injectable()
export class TasksService {
  deleteTask(id: string) {
    // Define collection, get some data for any checking and then update dataset
    const Tasks = this.db.collection('tasks')
    const data = await Task.findOne({ _ id: id })
    let res

    if (data.checkSomething) res = Task.updateOne({ _id: id }, { $set: { delete: true } })

    return res
  }
}

On the other side I can put all the service logic into the resolver and just leave the mongodb part in the service, but then the services are small and just replacing a simple mongodb call. So why shouldn't I put that also to the resolver.

@Resolver('Tasks')
export class TasksResolver {
  constructor(
    private readonly taskService: TasksService
  ) {}

  @Mutation(type => WriteResult)
  async deleteTask(
    @Args('id') id: string,
  ) {
    const data = await this.taskService.findOne(id)
    let res

    if (data.checkSomething) {
      const update = { $set: { delete: true } }
      res = this.taskService.updateOne(id, update)
    }

    return res
  }
}


@Injectable()
export class TasksService {
  findOne(id: string) {
    const Tasks = this.db.collection('tasks')
    return Task.findOne({ _ id: id })
  }

  updateOne(id: string, update) {
    const Tasks = this.db.collection('tasks')
    return Task.updateOne({ _ id: id }, update)
  }
}

What is the correct usage of the resolver and service? In both cases one part keeps nearly a one liner for each function, so why should I split that at all?

You're right that it's a pretty linear call and there isn't much logic behind it, but the idea is to separate the concerns of each class. The resolver, much like a REST or RPC controller, should act as a gateway to your business logic, so that the logic can be easily re-used or re-called in other parts of the server. If you have a hybrid server with RPC or a REST + GQL combo, you could re-use the service to ensure both REST and GQL get the same return.

In the end, it comes down to your choice on what you want to do, but separating the resovler from the service (having thin gateways and fat logic classes) is Nest's opinion on the right design.

In terms of best practice, the resolver or controller should be thought of as the manager. In this case (as is stereotypical), the manager shouldn't be doing any of the actual work except for telling the workers what to do. The Manager determines who (which worker/service) should do the work. Sometimes it might be two or more workers/services. They specialize in telling "who", "what" to do.

The workers on the other hand, execute on the actual task. In your case, another option would be to have a database "repository" for database commands like findOne, findOneByX, updateOne; and also a service to handle the actual logic of the task. So the service worker takes the instructions from the manager(resolver) and only uses their logic to tell their database fetching repository buddies what to fetch.

In this way, the manager manages who should do the task. The service contains the logic and tells the other repository methods focused on database fetches what to fetch.

// So you would have...
task.resolver.ts
task.service.ts
task.resolver.ts
  1. The task.resolver will contain one line that calls the task.service method
  2. The task.service will contain the logic to manage the task
  3. The task.repository will contain methods like what you have in your suggested task.service - essentially database only methods

Your service help you fetch the data from Database. Your Resolver help to delivery these data to user. Sometimes, the data that you delivery to user not the same with data from Database, so the Resolver will make up these data as user's demand before sending it to user.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM