Now we can finally complete the implementation of our GraphQL resolver for songs.
This resolver will be responsible for fetching and returning Song objects. To do so, it'll make use of MusicService, which is already available in the project. We have simply ported the existing code.
Create then open the backend/src/song/song.resolver.ts file and adapt it as follows:
import { Args, Query, Resolver } from '@nestjs/graphql'; import { MusicService } from '../musixmatch/services'; import { Inject } from '@nestjs/common'; import { TYPES } from '../musixmatch/ioc/types'; import { SongDto } from './song.dto'; import { Observable } from 'rxjs'; @Resolver('Song') export class SongResolver { constructor( @Inject(TYPES.MUSIC_SERVICE) private readonly musicService: MusicService, ) {} @Query(() => [SongDto]) songs(@Args('value') value: string): Observable<SongDto[]> { return this.musicService.findSongs(value); } }
As you can see, we have injected MusicService using the @Inject() decorator of NestJS. As we explained in the previous chapter, NestJS has great support for DI. Notice that we have also passed the injection token so that the correct implementation can be identified and injected for us by NestJS.
Also, we have implemented a method called songs that accepts an argument and returns Observable.
There are additional things to notice in that code:
- The @Resolver decorator indicates that this class is a resolver.
- The @Query decorator describes what kind of objects this resolver resolves; in this case an array of SongDto objects.
- @Args links the query argument and the resolver function argument.
The different decorators listed in the preceding are all part of the NestJS GraphQL plugin, but ultimately, they rely on other libraries such as type-graphql (https://github.com/MichalLytek/type-graphql). The GraphQL plugin of NestJS mainly gives us syntactic sugar/easy-to-use abstractions, but we could also achieve the same results without it.
What matters here is that our resolver simply takes the search text value from the query and passes it to the MusicService, which in turn contacts the MusixMatch API to fetch the results. All of this, of course, happens asynchronously.
We could go further and fetch only the exact dataset that we are interested in, but we'll skip that to keep this tutorial simple.