hapi-swaggered icon indicating copy to clipboard operation
hapi-swaggered copied to clipboard

Using Hapi 15.x multiple connections returned an error

Open sikancil opened this issue 8 years ago • 0 comments

I tried to build a project which divide into several connections which contains API on each connection, and expect to have API documentation for it. And it's returned and error:

Error: Server method function name already exists: resources which referencing to this code at L56

I have no idea if somebody has got the same idea and/or issue for this error.

My codes has more complex than below, it do the similar way like Glue does, which I don't use in this case.

Illustration in codes:

//-- I need to have more than one connections

//-- Registering new connection as "ONE" at 8080
server.connection({
  host: 'one.app.local.host',
  port: 8080,
  labels: 'one'
});

//-- Registering new connection as "TWO" at 8090
server.connection({
  host: 'two.app.local.host',
  port: 8090,
  labels: 'two'
});

//-- Registering Inert & Vision for both connections ( ONE and TWO )
server.register([
  require('inert'),
  require('vision')
], {
  select: [ 'one', 'two' ]
}, function(error){
  if (error) {
    throw error;
  }
});

//-- Registering Hapi-Swaggered & Hapi-Swaggered-UI to connection "ONE"
server.register([
  {
    register: require('hapi-swaggered'),
    options: {
      auth: false,
      basePath: '/',
      host: 'one.local.host:8080',
      schemes: ['http'],
      consumes: [ 'application/json' ],
      produces: [ 'application/json' ],
      requiredTags: [ 'one' ],
      responseValidation: true,
      info: {
        title: 'ONE API Documentation',
        description: 'API documentation for connection ONE',
        version: '1.0'
      }
    }
  },
  {
    register: require('hapi-swaggered-ui'),
    options: {
      title: 'ONE App',
      path: '/docs',
      auth: false,
      authorization: false,
    }
  }
], {
  select: [ 'one' ]
}, function (error) {
  if (error) {
    throw error;
  }
});

//-- Registering Hapi-Swaggered & Hapi-Swaggered-UI for connection TWO
server.register([
  {
    register: require('hapi-swaggered'),
    options: {
      auth: false,
      basePath: '/',
      host: 'two.local.host:8090',
      schemes: ['http'],
      consumes: [ 'application/json' ],
      produces: [ 'application/json' ],
      requiredTags: [ 'two' ],
      responseValidation: true,
      info: {
        title: 'TWO API Documentation',
        description: 'API documentation for connection TWO',
        version: '1.0'
      }
    }
  },
  {
    register: require('hapi-swaggered-ui'),
    options: {
      title: 'TWO App',
      path: '/docs',
      auth: false,
      authorization: false,
    }
  }
], {
  select: [ 'two' ]
}, function (error) {
  if (error) {
    throw error;
  }
});

Why I did register the both plugins twice?

It's because I need the plugins to apply for selected connections ( ONE and TWO ). That's why I implement server.register twice, or might more if have more connections to have hapi-swaggered for documenting API on preferred connections.

Then it return these error:

Error: Server method function name already exists: resources
    at Object.exports.unique.exports.contain.exports.reachTemplate.exports.assert.condition [as assert] (/home/itsme/NodeApp/node_modules/hapi/node_modules/hoek/lib/index.js:736:11)
    at internals.Methods._add.normalized [as _add] (/home/itsme/NodeApp/node_modules/hapi/lib/methods.js:47:10)
    at internals.Methods.add (/home/itsme/NodeApp/node_modules/hapi/lib/methods.js:26:21)
    at module.exports.internals.Plugin.parent.auth.internals.Plugin.register.internals.Plugin.method (/home/itsme/NodeApp/node_modules/hapi/lib/plugin.js:540:31)

    at Object.module.exports.register.next (/home/itsme/NodeApp/node_modules/hapi-swaggered/lib/index.js:56:13)
    ~^^^~ here above.. I realized the error raised caused by registering hapi-method more than one for the same method name of "resources"

    at Object.target [as register] (/home/itsme/NodeApp/node_modules/hapi/node_modules/joi/lib/object.js:77:34)
    at each (/home/itsme/NodeApp/node_modules/hapi/lib/plugin.js:318:14)
    at iterate (/home/itsme/NodeApp/node_modules/hapi/node_modules/items/lib/index.js:36:13)
    at Object.exports.serial (/home/itsme/NodeApp/node_modules/hapi/node_modules/items/lib/index.js:39:9)
    at Object.module.exports.internals.Plugin.parent.auth.internals.Plugin.register.each [as register] (/home/itsme/NodeApp/node_modules/hapi/lib/plugin.js:321:11)
    at /home/itsme/NodeApp/lib/engine.js:866:28
    at iterate (/home/itsme/NodeApp/node_modules/hapi/node_modules/items/lib/index.js:36:13)
    at done (/home/itsme/NodeApp/node_modules/hapi/node_modules/items/lib/index.js:28:25)
    at Object.method (/home/itsme/NodeApp/services/www/configs/hapi-auth-jwt2.pluginmethod.js:101:4)
    at /home/itsme/NodeApp/lib/engine.js:869:26
    at /home/itsme/NodeApp/node_modules/hapi/node_modules/hoek/lib/index.js:854:22
    at nextTickCallbackWith0Args (node.js:452:9)
    at process._tickCallback (node.js:381:13)
    at Function.Module.runMain (module.js:449:11)
    at startup (node.js:139:18)
    at node.js:999:3
[ERROR] 11:38:23 Error

I realized the error raised caused by applying the Hapi server.method more than one for the same method name of resources. Yeah.. I knew.. it's because I did register the plugins more than one.

I start to inspect directly to the code /lib/index.js L56

Then.. I done this way at L56 and the results comes perfectly as expected ! :)

    //-- Check if current "resources" method is already defined
    if (plugin.methods.resources === undefined) {
      plugin.method('resources', resourcesGenerator, {
        cache: settings.cache,
        generateKey: internals.keyGenerator
      })
      resourcesGenerator = plugin.methods.resources
    }

Please.. I wish request update to the codes on yours might do the same way. Or maybe somebody have another solutions for this case.

Thanks.

sikancil avatar Dec 07 '16 05:12 sikancil