outmoded / discuss Goto Github PK
View Code? Open in Web Editor NEWThe "mailing list"
The "mailing list"
I've been trying to get socket.io going without any success. I found the hapi-socket plug-in, but that causes a crash, for which I've created an issue (jeltok/hapi-socket#1). Does anyone have a working sample with the latest version of Hapi?
According to hapijs code style guide mentioned specific way to call callback
If a function takes a callback argument, it must be called on process.nextTick() .
Otherwise, the argument name must be next to clearly declare that it may get
called on same tick
Which is different than usual way of calling callback. I looked around on internet but unable to find any solid reason for it. Why did hapijs choose to use this specific method to call callback ?
I am sorry if this issue is not belong to here ..
Is there a convenient way to do this? It'd be simpler to just disable authentication while testing basic API functionality.
Create a document that lays out the "rules" for lab test layouts for the hapijs universe. The current proposal is:
[...] function names but instead of '#name' use 'name()'
any non-func specific tests should be in the top describe
and groups should use lower case titles (e.g. 'vision' + 'multiple engines' + 'returns error on..')
testing for classes should use the class name in first char uppercase ('Response')
generic integration tests should just be in the top outside a describe
Thoughts? Concerns? Clarifications?
I found a nice little repo showing different frameworks handling a very basic web application. I thought it would be good to have Hapi as an example as well.
Sample app to compare code complexity: expressjs vs python, php and ruby frameworks
https://github.com/komarserjio/notejam
I wouldn't mind doing this but I thought maybe someone who is part of the Hapi team might want to instead. I don't want to just port over the https://github.com/poeticninja/hapi-ninja/ boilerplate if that is not the way the Hapi people want the example to be.
Thoughts?
Hi, I've got the following payload being submitted:
show[id]=55&show[title]=Black+Impulse&show[links][][kind]=twitter&show[links][][url]=https://twitter.com/blackimpulses&show[links][][title]=&show[links][][kind]=facebook&show[links][][url]=https://facebook.com/blackimpulses&show[links][][title]=&show[links][][kind]=website&show[links][][url]=http://blackimpulse.co.uk&show[links][][title]=blackimpulse.co.uk&show[links][][kind]=website&show[links][][url]=&show[links][][title]=
This is represented in our UI as:
I'd expect the payload object to be parsed to something like:
{
"show": {
"id": "55",
"title": "Black Impulse",
"links": [
{
"kind": "twitter",
"url": "https://twitter.com/blackimpulses",
"title": ""
},
{
"kind": "facebook",
"url": "https://facebook.com/blackimpulses",
"title": ""
},
{
"kind": "website",
"url": "http://blackimpulse.co.uk",
"title": "blackimpulse.co.uk"
},
{
"kind": "website",
"url": "",
"title": ""
}
]
}
}
Instead, I get:
{
"show": {
"id": "55",
"title": "Black Impulse",
"links": [
{
"kind": [
"twitter",
"facebook",
"website",
"website"
],
"url": [
"https://twitter.com/blackimpulses",
"https://facebook.com/blackimpulses",
"http://blackimpulse.co.uk",
""
],
"title": [
"",
"",
"blackimpulse.co.uk",
""
]
}
]
}
}
Is there a way I can get what I really want, without specifically numbering the fields in the form? Here's the HTML to the form: https://gist.github.com/miksago/0b6e344c94368169197e
At present, I'm working around it by doing an awful loop + zip thing, but it think what I'm wanting to get should be given by default.
Thoughts? Am I doing something wrong?
How to serve static directory, when html5 mode (window.history.pushState) is required by client app instead of hashbang mode?
I want to define routes, when to serve static directory. E.g.
// It's OK
plugin.route({
method: 'GET',
path: '/{param*}',
handler: {
directory: { path: 'public/build' }
}
});
// It's OK
plugin.route({
method: 'GET',
path: '/stories/{param*}',
handler: {
directory: { path: 'public/build' }
}
});
// Problem is HERE, because this is not allowed
plugin.route({
method: 'GET',
path: '/stories/{id}/{param*}',
handler: {
directory: { path: 'public/build' }
}
});
This is probably my misunderstanding of routing. So how to serve static directory when user comes to webpage and webpage uses html5 mode?
Thank you.
I would like one of my authentication scheme to be based on path parameter.
Here is what i'm trying to do for my API:
I am currently using the 'hapi-auth-basic' plugin which do not allow the validate function to look in the request. My ideas was either to :
Which solution do you think is better? Do you have any other ideas which could be better? Any authentication scheme which could better suit my need?
Anyone have an example of a basic handlebars template that loads into a view?
From the hapi view tutorial, it sounds like the compiling happens on the server. So, I'm not sure what actually still needs to be in my index.html template if I'm serving it via hapi.
I'm new to both hapi and handlebars, so forgive me if this is the wrong spot to ask.
Thanks,
Don
I read somewhere that Hapi.js had Multiparty "baked-in", I have read the Multiparty docs but I cant find any parallel in any Hapi.js file upload snippet I have seen.
Is there any official documentation? Thanks
Hi!
I have some multipart/form-data that gets posted to the webapp. I need some of the data in the webapp, but the rest should be forwarded to the API. Im currently using Wreck as my api-client.
Like this:
POST webapp/some_endpoint - { key1: "key1", key2 : "key2", "files": [file1, file2] }
POST api/{key1}/some_other_endpoint - { key1: "key1", key2 : "key2", "files": [file1, file2] }
Do I need to temp store the files etc? Do I need to create a new multipart/form-data body?
I cannot seem to find any good way todo this. Tips are welcome :)
I am trying to configure the view engine for my server from a centralized JSON file. Below is a snippet of the part that I am using. The port setting works but the view engine part causes an error. Strangely, if I configure the server using the server instance, it works. Any idea what I'm doing wrong? Thanks
// Does not work
development: {
port: parseInt(process.env.PORT, 10) || 3000,
hapi: {
options: {
views: {
path: rootPath + '/views/',
engines: {
html: require('swig')
}
}
}
}
},
// WORKS!
/* Configure view engine */
server.views({
engines: {
html: require('swig')
},
path: process.cwd + 'views'
});
The error:
Debug: hapi, internal, implementation, error
TypeError: Uncaught error: Object function (err, result) {
return internals.wrap((err !== null && err !== undefined ? err : result), request, finalize);
} has no method 'view'
Are there docs on how to version APIs somewhere? Can someone point me to them? Thanks
We want the hapi.js community to be the model of building and nurturing a diverse, open, and welcoming community. This can include how we name modules, what gender pronouns we use, to the makeup of the leadership, etc.
Please use this thread to highlight areas we should actively work on to improve, to list existing patterns that are offensive or discourage diversity, or to make other suggestions.
If you feel uncomfortable posting in public, please feel free to contact me directly [email protected].
And of course, this thread as all other threads must only include constructive and friendly discourse.
I found many issues (specially labelled with bug) in hapijs
projects without description. It is difficult to understand what exactly issue is. Please make sure that issue creator adds description to issue. This will be very helpful.
Hi,
I'm looking to specify on a route config a permission that is required for a user to have to execute the route, in the config I would like to specify a string that is a permission string which a user must have, for example. 'this.permission.execute'
I would like to do a check against data i have retrieved from the database based on a session before the handler is executed. I know i could use the config.description field of the route and then get the value in a preHandler request using request.route.description and do my validation there, I just wanted to know if there was a cleaner and more efficient way of achieving what i'm trying to do
Thanks in advance.
Danny
I'm currently writing a Hapi based service for processing images with Graphicsmagick. My route handler looks something like this:
var gm = require('gm').subClass({ imageMagick: true });
var handler = function (request, reply) {
// Get target image size and type from parameters
// ...
gm(sourceImage)
.resize(imageSize.width, imageSize.height)
.gravity('Center')
.stream(imageExtension, function (err, stdout, stderr) {
if (err) { return reply(plugin.hapi.boom.badImplementation); }
// Stream the converted image, set mime type according to file extension
reply(stdout).type(contentTypes[fileExtension]);
}
);
};
This works great so far. However, I wrote a test with Lab to validate the image conversion and the streamed content is not be recognized as an image by Graphicsmagick (nor any similar image library):
var gm = require('gm').subClass({ imageMagick: true });
var server = require('../');
var Lab = require('lab');
var lab = exports.lab = Lab.script();
lab.it('should resize the image correctly', function (done) {
server.inject({
url: '/my/image/300x300',
header: { 'Accept-Encoding': 'identity' }
}, function (res) {
// Read the size (width and height) of the given image
gm(res.rawPayload).size({bufferStream: true}, function (err, value) {
// This breaks, because gm could not identify the image type based on the given stream
Lab.expect( value.size ).to.equal('300x300');
done();
});
});
});
Did I miss something while creating the stream response? I also noticed, that Hapi still sets Content-Encoding: gzip
even for (already compressed) image binaries, regardless of the Accept-Encoding
setting (normally, only text based files should be gzipped). Is there a way to disable this?
I'm trying to use hapi with node-mysql to create a rest api. I've not used streams in anger and am trying to work out where I'm going wrong. This is my route config:
{
method: 'GET',
path: '/query/stream',
config: { auth: false },
handler: function(request, reply) {
var query = db.query('SELECT * FROM user LIMIT 5000');
reply(query.stream());
}
}
db is a connection pool created using mysql.createPool()
.
This is the error:
Debug: hapi, internal, implementation, error
TypeError: first argument must be a string or Buffer
at ServerResponse.OutgoingMessage.write (http.js:851:11)
Any help would be much appreciated, thanks
I am wiling to contribute in project from this organization. Where is great place to start contribution ? Can we have single place where contributor can check issue they can solve from various repository of organization ?
I think the merits in this idea are there not sure on execution.
But based on the ideas of hapis server config been thinking it could be possible to pull together solutions faster using services.
https://github.com/dreamineering/the-bach
I've mainly been working on front end stuff but really want to get into services side of things and very keen to learn and hopefully teach some ideas around hapi so other developers can get up to speed quickly.
Is there support for multiple static folders? I tried the following and it did not work, all the files in the second folder were not found. Thanks
server.route({
method: 'GET',
path: '/{path*}',
handler: {
directory: {
path: 'bower_components',
listing: false
}
}
});
server.route({
method: 'GET',
path: '/assets/{path*}',
handler: {
directory: {
path: './../client/app',
listing: false
}
}
});
How convenient is there to use prerequisites for most of the code? Or is this a bad way to use the prerequisites?
Example if you split it up like this:
The handlers will be very lightweight and the prerequisites will be reusable.
Code example:
{
method: 'POST',
path: '/api/news',
config: {
handler: function(request, reply){
reply.redirect('news/' + request.pre.news.id);
},
pre : [
{ method: 'validateSomeDataAgainsDatabase' },
{ method: 'getUserFromDataBase', assign: 'user' },
{ method: 'insertNewsIntoDatabase', assign: 'news' }
]
}
}
Any great minds out there with some opinions? Thanks :)
Hapi has these paths
path: the directory that contains your main templates
partialsPath: the directory that contains your partials
helpersPath: the directory that contains your template helpers
http://hapijs.com/tutorials/views
If you have Handlebars partials on the server stored in partialsPath or if you have helpers stored in helpersPath, how do you register them in a template stored in path so that when you reply with the rendered view, it works?
Or is it automatic?
for example, would it automatically search the partialsPath for a person.html file and just use it?
{{#each people}}
{{> person}}
{{/each}}
Thanks.
Don
I'm building a product using Hapi and was surprised that Hapi doesn't handle SIGINT and SIGTERM natively. Is there a reason for that? I wrote https://github.com/KyleAMathews/hapi-death to capture the two and call server.stop()
but am curious about the reasoning behind this.
I noticed recently big excitement about Generators in Node > 0.11.2. Probably most noticeable is new framework koajs, which utilizes Generators instead of callbacks. Main goal is to create easier code to read, without callbacks.
I know that it still can take some time before 0.12 gets around and becomes production ready. Just wondering if you have considered utilizing Generators inside Hapi in future. For some reason frameworks which make async code look like sync are fairly popular (meteor, koajs).
What's the best way to handle errors on prerequisites without coupling HTTP to internal functionality? Let's assume that I want to validate if a given thing exists in a database, before something else, and then return a HTTP 404 error to the client if it does not. Should I deal with Boom
instances directly on the server method used as prerequisite or on the handler?
this is my crumb setup
var crumb = {
plugin: require('crumb'),
options: {
cookieOptions: {
isSecure: false
},
size: 256,
restful: true
}
};
making a POST
to
{
path: '/test-route',
method: 'POST',
handler: webControllers.test
}
webControllers.test looks like
test: function(req, rep){
console.log(req.headers);
rep('taaddaaaa');
},
I get a 403. Looking a the request parameters looks like the cookie with the crumb is getting passed. I am not sure what am I doing wrong. My apologies for my n00bness!
I'm building a stub service powered by MongoDB. Routes are added to the server on server start and when a new stub service is added to the DB. I need the ability to remove/unregister a route while the server is still running after a stub service is deleted from the DB.
Is this possible in Hapi?
I am using Hapi.js to implement RESTful API for my mobile application. I have integrated Good for logging requests, errors, and other events. It works very well for me. However it is not clear how to log request and response payloads (JSON objects) to console and file.
I would appreciate any help.
I would like to allow a HAPI client to access a REST API served by another Hapi application without using AJAX. What is the best practice in this case?
I considered using Wreck(https://github.com/hapijs/wreck) in the clients controllers to access the API. How do others go about this? Are there code examples somewhere? Thanks
Hi , I am new to Hapi and this is a very basic question.
We are planning to create a REST Api using Hapi.
Our Application has different features like Chat , Forums Quiz etc. Now my question is should I create separate plugins for these features or just follow the basic this ie, creating routes,handlers, validation etc.
Which is a better way for structuring the entire code?
(I had asked this query in hapijs/hapi#2204. Since this is the correct platform I am asking the question again here)
Hello,
I have a scenario where I want to redirect to an URL from within a plugin, before the request is processed further down the request lifecycle.
I wrote a plugin that looks something like this:
plugin.ext('onRequest', function(request, reply)) {
if(someCondition) {
reply.redirect(somePath);
} else {
reply();
}
}
It seems however that my redirect call is ignored, and the request follows trough as as normal. Am i missing something here?
Regards,
Daniel
I have implemented cookie based authentication session for Hapi application using hapi-auth-cookie plugin. I want to use same session in socket.io.
I know I would have to use iron to validate the cookie. But I don't know how to use Iron directly, with the cookie configuration I have set for plugin.
io.set('authorization', function (handshakeData, accept) {
var cookies;
if (handshakeData.headers.cookie) {
cookies = cookie.parse(handshakeData.headers.cookie);
if (cookies['sid']) {
// Code to verify cookie.
return accept(null, true);
}
} else {
return accept('No cookie transmitted.', false);
}
accept(null, false);
});
I need help with writing // code to verify the cookie.
I am building a social network and there are a lot of times that I need to get the last activities, so I call using AJAX a rout, get the count of activities and how the user.
But I am not sure how I can call a HAPI route as a new activity happens, than I receive from the server the new count, without having to query again.
Keep the socket connection open, so that I can reply back to all that opnened this socket with the server.
Any examples or pointers of how to do it using HAPI would be great.
I'm using bell for yahoo authentication. I then am using wreck to make a call to the specific api. My best guess is that the api call itself needs the access token, but I don't see that token in the authentication data returned after logging in.
Authentication bit:
server.route({
method: ['GET', 'POST'], // Must handle both GET and POST
path: '/login', // The callback endpoint registered with the provider
config: {
auth: 'yahoo',
plugins: {
'hapi-auth-cookie': {
redirectTo: false
}
},
handler: function (request, reply) {
var creds = {};
creds.creds = request.auth.credentials;
creds.token = request.query.oauth_token;
request.auth.session.set(creds);
return reply.redirect('/');
}
}
});
Api call:
server.route({
method: 'GET',
path: '/',
config: {
auth: 'session'
},
handler: function (request, reply) {
var url = 'https://fantasysports.yahooapis.com/fantasy/v2/leagues;league_keys=328.l.5668/standings?format=json';
Wreck.get(url, function (err, res, payload) {
console.log(payload);
});
reply.view('index', { title: 'hello world' });
}
});
The payload in the wreck call is:
{"error":
{
"lang":"en-US",
"description": "Please provide valid credentials. OAuth oauth_problem=\"unable_to_determine_oauth_type\",
realm=\"yahooapis.com\""
}
}
Is there a preferred method to coerce, sanitize user input using Hapi.js? Joi only does validation it seems. Thanks
Hi,
I'm using bell to login with Yahoo. It provides the access token and secret once logged in, however it seems that it does not provide the session_handle, unless I've missed something. Is there a way to expose this property?
Thank you.
What is the preferred way to inject dependencies? I have a few application settings that I would like to use in various parts of my application
Coming from Express. I could get resource ranges. for example, to get users 1 to 5
/api/v2/users/1..5
this.get(path + '/:a..:b.:format?', function(req, res) {
var a = parseInt(req.params.a, 10);
var b = parseInt(req.params.b, 10);
var format = req.params.format;
range(req, res, a, b, format);
});
range: function(req, res, a, b, format) {
var range = profiles.slice(a, b + 1);
switch (format) {
case 'json':
res.send(range);
break;
case 'html':
default:
var html = '<ul>' + range.map(function(user) {
return '<li>' + user.name + '</li>';
}).join('\n') + '</ul>';
res.send(html);
break;
}
}
How can I achieve this using Hapi.js? Thanks
Following the issue at hapijs/hapi.
I'm trying to implement a small file upload module that would support either multipart/form-data
and application/json
.
One of the requirements is to be able to pipe the image to another server.
A test case can be seen here: https://gist.github.com/Couto/127ca8a6bd28ecc4a084
What would be best way to handle multiple types of uploads on the same endpoint, or how would you think it would be best solution to handle this?
I think it would be good practice to have a bit more tooling around hapi development process.
What about creating a set of rules for jshint/eslint and jscs ?
Linting might spot a few bugs and jscs would help contributors about the strict styling enforced in the project.
Hi! I want to pass a custom validation schema to validate input. A query parameter in the GET url will be used to retrieve an object from the database, which I will then use to build a validation schema based on the rules defined in that object. I then want to pass that schema to validate input parameters.
Is this possible / is there a recommended way to achieve this? Thanks
A lot of JSON schema validation libraries support custom checks or rules which are supplied by the library user in the form of functions. Does Joi support this?
Can anyone list a conclusive negative reason against using "use strict" in the hapijs modules? There are documented cases where omitting "use strict" will prevent v8 optimization where adding "use strict" allows the code to be optimized.
It would also suss out bad practices and mistakes before PRs are even opened.
From what I've read, worse case scenario is "use strict" does nothing and is just a magic string at the top of a file.
I have 2 routes on my api, /album and /song and as such, I have 2 handler functions. What I want to do is when I call /album, the handler will sometimes want to gather information about the songs in one round trip to the server. Is there a pre-described way of calling a route handler from inside another route handler? I figured you could access the server route table and trigger the call manually but it feels really dirty.
I want to add an "internal" scope to all routes and then add additional scopes to certain routes that regular users and/or admins can access. Is there a way I can do this?
We want to have a good catch-all exception page for our application.
We have achieved this if we ever have errors triggered within our handlers using a onPreResponse
event as described here: http://hapijs.com/api/#error-transformation.
However if there is an error triggered when the view is being rendered (due to bad data into the view context), how can we catch those errors and replace the response? It seems that the view rendering is being done after the onPreResponse
event.
I wanted to check out Hapi for a long time and I took a couple hours today to do so! This is great :)
In order to have a "real-world" example to play with, I decided to create a plugin to interract with Superfeedr from a Hapi app. One could create a simple feed reader with it for example, or a tool like IFTTT... etc.
Anyway, I cam up with this "stub":
var path = require('path');
var urlParser = require('url');
var http = require('http');
var https = require('https');
var querystring = require('querystring');
exports.register = function (plugin, options, next) {
// Sends a request to Superfeedr. Do not use directly. Use the subscribe and unsubscribe methods rather!
plugin._superfeedrRequest = function(mode, url, id, opts, cb) {
var post_data = querystring.stringify({
'hub.mode': mode,
'hub.topic': url,
'hub.callback': urlParser.format({
'protocol': options.webhooks.scheme,
'hostname': options.webhooks.host,
'port': options.webhooks.port,
'pathname': path.join(options.webhooks.base, id)
})
});
if(opts.retrieve) {
post_data['retrieve'] = true;
}
if(opts.format) {
post_data['format'] = opts.format;
}
if(opts.secret) {
post_data['hub.secret'] = opts.secret;
}
var post_options = {
'host': 'push.superfeedr.com',
'port': '443',
'path': '/',
'auth': [options.login, options.password].join(':'),
'method': 'POST',
'headers': {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': post_data.length
}
};
var post_req = https.request(post_options, function(res) {
var data = '';
res.setEncoding('utf8');
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function() {
if(res.statusCode == 204 || res.statusCode == 200) {
cb(null, data);
}
else {
cb(new Error(res.statusCode, data));
}
})
});
post_req.write(post_data);
post_req.end();
}
// Subscribe is called from anywhere in the hapi app like this
// Params
// - url: url of the feed/topic to which you want to subscribe
// - id: unique id of the feed/topic uou want to subscribe. This is important to identify unique notifications. You should use some kind of primary key.
// - opts:
// - retrieve: set to true if you want previous items from the feed
// - format: 'atom' or 'json'
// - secret: a unique secret used to compute an HMAC key for notifications.
// - the callback will be called with the result of the subscription. First param is error, second param is body if retrieve:true.
plugin.subscribe = function(url, id, opts, cb) {
plugin._superfeedrRequest('subscribe', url, id, opts, cb);
}
// Unsubscribe is called from anywhere in the hapi app like this
// Params
// - url: url of the feed/topic to which you want to subscribe
// - id: unique id of the feed/topic that you used to subscribe
// - the callback will be called with the result of the subscription. First param is error, second param is body if retrieve:true.
plugin.unsubscribe = function(url, id, cb) {
plugin._superfeedrRequest('unsubscribe', url, id, {}, cb);
}
plugin.route({
method: 'POST',
path: path.join(options.webhooks.base, '{feed_id?}'),
handler: function(request, reply) {
// The event is triggered so that anyone who listens to 'notification' on the superfeedr plugin (how do we do that?)
// will recive the feed_id, the RAWBODY (if we are able to extract it), the topic/feed url and the request object
// if they want to debug it.
plugin.events.emit('notification', request.params.feed_id, RAWBODY, request.headers['x-pubsubhubbub-topic'], request);
reply('Thanks Superfeedr');
}
});
next();
}
exports.register.attributes = {
multiple: false,
name: 'Superfeedr',
version: '1.0.0'
};
From there, there are several questions/problems that I have:
application/atom+xml
. Hapi does not like this and serves a 415. Any idea why? Can we force Hapi to be a little bit more agnostic? If not, we can still force subsriptions to JSON.server.plugins.superfeedr.subscribe('http://...', '123', {}, function() {...});
right? The problem is that server.plugins
is desperately empty ({}
) everywhere in my app. Any idea why?server.plugins.events.on('notification', function(feed_id, body, url, request) {...});
but... server.plugins is still empty :(Any help with any of these issues would be greatly appreciated!
I've just started playing with hapi, and so have been visiting the API doc a lot.
Awesome to see this level of detail in the doc - much thanks!
OTOH, I've found the various "object schema" there to be difficult to follow, as they often seem to become deeply nested <ul>
's. It seems like it could be improved, but not sure the best course of action.
Some thoughts:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.