Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to hapi v17. #104

Merged
merged 1 commit into from
Nov 6, 2017
Merged

Update to hapi v17. #104

merged 1 commit into from
Nov 6, 2017

Conversation

WesTyler
Copy link
Contributor

@WesTyler WesTyler commented Oct 21, 2017

Updates to hapi v17 and lab v15

Breaking Changes:

  • Remove "connections" and "onPreConnection" from manifest.
  • Return async function instead of using a callback or native Promise.
  • Change "preRegister" contract from callback to async function.
  • Change manifest shape from manifest.registrations array to manifest.register.plugins array.
  • Change expected plugin object shape to match hapi v17 expectations.

Non-Breaking Changes:

  • Hand plugin and registration options straight to hapi for validation at registration time.
  • Single server.register call instead of one per plugin.

@WesTyler WesTyler mentioned this pull request Oct 21, 2017
Copy link
Contributor

@csrl csrl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by 'move plugin attributes from children of "register" to siblings of "register"'? I don't see a need for any structure change to the manifest.

lib/index.js Outdated
let path = plugin.register;
if (relativeTo && path[0] === '.') {
path = Path.join(relativeTo, path);
}

plugin.register = require(path);
pluginObject.plugin = require(path);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this change - the required field is 'register' not 'plugin'. I don't see any change regarding that in the hapi 17 docs.

Copy link
Contributor Author

@WesTyler WesTyler Oct 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's entirely possible that I'm misunderstanding, but here is the change I'm looking at.

Switch plugins to use a simple object with a register property. All the other attributes move to the object alongside register.

and

Change server.register() to support { plugin, options } instead of { register, options }

Additionally (and this may very well be an error on my side) when I try to register the plugins using

exports.register = function (server, options) {

    server.expose('hello', options.who || 'world');
};

exports.register.attributes = {
    name: 'helloworld',
    multiple: false
};

as it was before, I get the error:

Error: Invalid plugin options {
  "plugin": {
    "register": function (server, options) {\n\n    server.expose('hello', options.who || 'world');\n},
    "name" [1]: -- missing --
  }
}

[1] "name" is required

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I misread the documentation.

I'm tempted to have glue only call server.register() a single time, passing all plugins at once.

In which case, the new schema would be:

{
    options: Joi.object({
        relativeTo: Joi.string(),
        preRegister: Joi.func().allow(false)
    }),
    manifest: Joi.object({
        server: Joi.object(),
        register: Joi.Object({
           plugins: Joi.array().items(
             Joi.string(),
             Joi.object()
           ),
           options: Joi.any()
        ))
    })
}

example manifests:

{register: {
  plugins: ["myplugin"]
}}
{register: {
  plugins: [require("myplugin")],
  options: registerOptions
}}
{register: {
  plugins: [{plugin: "myplugin", options: myPluginOptions}]
}}
{register: {
  plugins: [
    {plugin: "myplugin", options: myPluginOptions},
    {plugin: "otherplugin", options: otherPluginOptions, routes: overrideRegisterRoutesOption},
    "thirdplugin",
    {plugin: require("bestplugin"), options: bestsPluginOptions}
  ],
  options: registerOptions
}}

And from that, if an item from the register.plugins array is a string we'll require() it, otherwise we'll pass the register.plugins array directly to server.register() without any additional validation, and let hapi itself validate the input. As far as that goes, I'd be fine with simplifying the manifest schema to be:

Joi.object({
  server: Joi.object(),
  register: Joi.Object({
    plugins: Joi.array(),
    options: Joi.any()
  ))
})

As we don't care what format the registration options are, and we don't care what the plugin format is, except if its a string, we require() it. Let them pass whatever to hapi, where hapi is the source of truth to validate what is provided.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that. I'll do that refactor on this PR this weekend 👍

lib/index.js Outdated
if (typeof plugin === 'string') {
plugin = { register: plugin };
const pluginObject = { plugin };
if (typeof plugin.options === 'object') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'plugin' may be a string here, so its premature to reference 'plugin.options'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, the function still needs some love based on other changes still in the air 👍

@csrl csrl added the breaking changes Change that can breaking existing code label Oct 21, 2017
@WesTyler
Copy link
Contributor Author

Okay, I took a first pass at the changes we discussed above. I also tried to update the API.md to match. I don't love the wording in some parts, but I could use some input on how to make it more clear.

Is this implementation what you had in mind?

@csrl
Copy link
Contributor

csrl commented Oct 25, 2017

I pushed a work in progress review commit to 'review/pr104' branch to give you an idea of how I'm looking at it. If that makes sense to you, and you want to finish it off (updating the rest of the tests etc), please do.

@WesTyler
Copy link
Contributor Author

Ohhh excellent yes. I'm actually very happy to be removing Items and going to async/await. 👍 👍 👍

I'll wrap those changes in here this afternoon. Thanks!

@WesTyler
Copy link
Contributor Author

Alright, I did the async/await refactor and also went ahead and updated dev dependencies to lab@15 and code@5 to make use of the async/await features there.

lib/index.js Outdated
],
options: Joi.object()
}))
server : Joi.object(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no spaces before the colon

lib/index.js Outdated
});
});
}

// Create server
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might as well drop this comment - there are no other comments, and its not really pertinent to call out.

README.md Outdated
@@ -8,20 +8,20 @@ Lead Maintainer - [Chris Rempel](https://github.com/csrl)

Glue provides configuration based composition of hapi's Server object. Specifically it wraps

* `server = new Hapi.Server(Options)`
* one or more `server.connection(Options)`
* `server = Hapi.server(Options)`
* zero or more `server.register(Plugin, Options)`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it now wraps a single server.register call

README.md Outdated
* zero or more `server.register(Plugin, Options)`

calling each based on the configuration generated from the Glue manifest.

### Interface

Glue's [API](API.md) is a single function `compose` accepting a JSON `manifest` file specifying the hapi server options, connections, and registrations.
Glue's [API](API.md) is a single function `compose` accepting a JSON `manifest` file specifying the hapi server options and registrations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the word "file". It doesn't interact with any files.

Copy link
Contributor

@csrl csrl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just release 4.2.1 to fix the promise bug. So if you can rebase your PR ontop of current master, then squash the commits into a single one with a final commit message, I'll do a final review and merge it in. Thanks.

@WesTyler
Copy link
Contributor Author

Done and done! Thanks for the help getting this where it needed to be @csrl

@csrl
Copy link
Contributor

csrl commented Oct 30, 2017

I think I will hold off on releasing this until hapi 17 final lands. We could do a release candidate, but I'm not too motivated to do so. So if you want to update the package.json to reference hapi 17 instead of rc9, then it'll be a simple merge whenever hapi 17 is released. thoughts?

@WesTyler
Copy link
Contributor Author

Yeah, that sounds good to me 👍

I'll keep an eye on the state of the branch if Eran does anymore rcs just to make sure.

Breaking Changes:
  - Remove "connections" and "onPreConnection" from manifest.
  - Return async function instead of using a callback or native Promise.
  - Change "preRegister" contract from callback to async function.
  - Change manifest shape from manifest.registrations array to manifest.register.plugins array.
  - Change expected plugin object shape to match hapi v17 expectations.

Non-Breaking Changes:
  - Hand plugin and registration options straight to hapi for validation at registration time.
  - Single server.register call instead of one per plugin.
@WesTyler
Copy link
Contributor Author

WesTyler commented Oct 31, 2017

Also, the Travis build is going to fail since there is no install target yet for "hapi": "17.x.x". Just throwing that out there before a big red X appears next to my commit.

@WesTyler
Copy link
Contributor Author

WesTyler commented Nov 4, 2017

Looks like we are all good with the release of 17.0.0 yesterday.

@csrl csrl merged commit 465939b into hapijs:master Nov 6, 2017
@csrl
Copy link
Contributor

csrl commented Nov 6, 2017

Thanks @WesTyler. Nice work on this release. I'm actually not sure when I'll be updating to hapi 17 for the main project I work on with hapi. Do you have any interesting in taking over as maintainer for glue?

@csrl csrl added this to the 5.0.0 milestone Nov 6, 2017
@WesTyler
Copy link
Contributor Author

WesTyler commented Nov 6, 2017

Nice work on this release

Thank you, and thank you for the help with it!

Do you have any interesting in taking over as maintainer for glue?

If you are wanting to pass it off, then absolutely! We will be updating to hapi 17 and glue 5 at work soon, so I should have plenty of time to be hands on with it.

@csrl
Copy link
Contributor

csrl commented Nov 7, 2017

ok, I'll let you know - we'll make a decision next week on when/if we will port to hapi 17.

@WesTyler
Copy link
Contributor Author

WesTyler commented Nov 7, 2017 via email

@lock
Copy link

lock bot commented Jan 9, 2020

This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
breaking changes Change that can breaking existing code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants