Implementing the song resolver and leverage NestJS features

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

As shown in the official documentation of the plugin, it is also possible to write async functions that return Promise but we prefer to deal with RxJS observables instead.

There are additional things to notice in that code:

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.

This idea is kind of interesting: we can easily use GraphQL to expose an API that in fact serves as a gateway/facade in front of other APIs.

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.