DEV Community

Cover image for Build a NestJS Module for Knex.js (or other resource-based libraries) in 5 Minutes

Build a NestJS Module for Knex.js (or other resource-based libraries) in 5 Minutes

John Biundo on September 23, 2019

John is a member of the NestJS core team Ever wanted to integrate your favorite library into NestJS? For example, while Nest has broad built-in su...
Collapse
 
mtaylor769 profile image
Mike Taylor • Edited

Great article. I'm using Typescript and it was giving me this error in the getKnex() function:

src/next-knex/nest-knex.service.ts:40:30 - error TS2350: Only a void function can be called with the 'new' keyword.

40       this._knexConnection = new Knex(this._NestKnexOptions);
                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Enter fullscreen mode Exit fullscreen mode

did a bit of quick research and the fix is this:

      this._knexConnection = new (Knex as any)(this._NestKnexOptions);
Enter fullscreen mode Exit fullscreen mode

Keep up the great work!

Collapse
 
umasankarswain profile image
umasankar-swain
Collapse
 
fwoelffel profile image
Frédéric Woelffel

Another great article @johnbiundo 👏 This series is really interesting. Thanks for you work 👍

I have a few questions that might sound dumb but I'm going to ask them anyway:

  • I've noticed that the generated module is decorated as Global by default. Is that the way to go? Shouldn't we avoid global modules? Let's say I need a specific connection to a Postgres instance in module A and another connection to another instance in module B. If the NestKnexModule is global, won't that be an issue?
  • Second question is simply about the naming of the register and registerAsync methods: I thought that global modules were supposed to expose forRoot (and its async variant) and that module-scoped modules were supposed to expose register (and its async variant). Have I been wrong this whole time? Or is it just a matter of personal preference?

Again, thanks for your work! I wish those schematics were released sooner as they would have saved me some time :)
Can't wait for your next post.

Collapse
 
johnbiundo profile image
John Biundo

@fwoellfel, thanks! Glad it has been helpful!

Not dumb at all! I should probably discuss the use of @Global() in the article, so thanks for bringing it up. The main reason I use it is, to be honest, in a "utility" type module I find it convenient to register it once (usually in the root module), and then have it globally available. However you bring up an excellent point, and @Global() definitely has some side effects (such as breaking module encapsulation) and is usually to be avoided. I want to give this some more thought, and I have an idea or two on how to handle your Module A/Module B question, but need to test a few things out. I'll report back!

And your second question is good as well! To be honest, I hadn't quite sussed out that pattern of register vs. forRoot, but now that you mention it, I'll have to go back and look more closely.

Thanks so much for the thoughtful feedback. It really helps to have sharp eyes from people who have worked on dynamic modules. I hope to continue to improve these articles as a useful resource!

Collapse
 
umasankarswain profile image
umasankar-swain
Collapse
 
mtaylor769 profile image
Mike Taylor

I am getting this error from the /.constants. Why is this throwing an error for a constant?

Nest can't resolve dependencies of the NestKnexService (?). Please make sure that the argument NEST_KNEX_OPTIONS at index [0] is available in the NestKnexService context.

Potential solutions:
- If NEST_KNEX_OPTIONS is a provider, is it part of the current NestKnexService?
- If NEST_KNEX_OPTIONS is exported from a separate @Module, is that module imported within NestKnexService?
  @Module({
    imports: [ /* the Module containing NEST_KNEX_OPTIONS */ ]
  })
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ozanulutas profile image
Ozan Ulutaş

Hi. For the future readers;
Error complains about NestKnexService can not resolve injected dependency. In this case the dependancy is NEST_KNEX_OPTIONS which is a custom provider. To make the dependency injection work, the provider needs to be registered in the knex module. NEST_KNEX_OPTIONS provider is not included in this article. It is included in github link author provided.

import { connectionFactory } from './nest-knex-connection.provider';
import { createKnexProviders } from './knex.providers';

@Global()
@Module({
  providers: [
    KnexService,
    connectionFactory,
    ...createKnexProviders({/*...knex options*/}),
  ],
  exports: [KnexService, connectionFactory],
})
export class KnexModule {}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
johnbiundo profile image
John Biundo

Hi Mike,

Can you provide some more context for this error? Do you have a repository that you can share?

Best,
John

Collapse
 
gates17 profile image
gates17

hi, im new to nextjs and knex and im trying to build a custom api with both of these apps.
However, while following your guide, after running npm install im getting the following error
npm ERR! nest-knex@1.0.0 build: tsc
npm ERR! Exit status 2
which are related to jest-diff module.
Can u maybe point me out any directions on how to fix this and finish the current integration of knex with nestjs?
ty

Collapse
 
gates17 profile image
gates17

apparently this error seems to be a conflict between @types/jest and typescript versions, and can be solved by updating both with jest v26.0.4 and typescript above v3.8 (v3.9.6 currently).
sry for the bother

Collapse
 
shamilw profile image
Shamilw

Good afternoon, I am using your package github.com/nestjsplus/knex
and I wanted to wrap the user.service in a repository and I got errors

Potential solutions:

  • If UserRepository is a provider, is it part of the current UserService?
  • If UserRepository is exported from a separate @Module, is that module imported within UserService? @Module({ imports: [ /* the Module containing UserRepository */ ] }
Collapse
 
pinich profile image
Pini Cheyni

Have you tried newer version of knex ^1.0.3 ?
There are some breaking changes for me line there is no exported interface "Config".

Collapse
 
monirul017 profile image
Monirul Islam

is it possible to get knex debug data into knexmodule?

Collapse
 
zyles profile image
Zyles

Can you update this article? It seems out of date.

What is in constants.ts ?

And I get error 'knex_1.Knex is not a constructor'

Maybe a working git repo would be nice. Something is missing.

Collapse
 
koakh profile image
Mário Monteiro

another awesome post from John :)
follow the tutorial and works in current date only fails in bellow fix

import { Config } from 'knex';
Enter fullscreen mode Exit fullscreen mode

with

import { Knex } from 'knex'

export interface NestKnexOptions extends Knex.Config {}
Enter fullscreen mode Exit fullscreen mode

and one must update this dependencies

"devDependencies": {
  "@types/jest": "^26.0.24",
  "typescript": "^4.3.5"
}    
Enter fullscreen mode Exit fullscreen mode

thanks John

Collapse
 
promise111 profile image
Promise Ihunna

Can't seem to get past "nest g -c @nestjsplus/dyn-schematics dynpkg nest-knex".

Collapse
 
aboyd002 profile image
Arran Boyd

Having the same issue, did you manage to get the package to work?

Collapse
 
promise111 profile image
Promise Ihunna

I think I did, I will have to read through my code and find out. I'll get back to you

Collapse
 
umasankarswain profile image
umasankar-swain