How do I use https.request to perform a get request? - node.js

I've been trying to use https.request() to do a perform a get request, but I don't know how I would it. '
The current code I have is
const url="https://api.openweathermap.org/data/2.5/weather?q="+query+"&appid="+apiKey+"&units="+unit;
https.get(url,function(response){
However I would like to use https.request because I am trying to understand the concept, and the code I got so far is
var options={
method: "GET",
hostname:"api.openweathermap.org",
path: "/data/2.5/weather?q="+query+"&appid="+apiKey+"&units="+unit,
auth: "Eric:"+apikey
}
https.request(options,function(response){
I don't know why the http basic authentication did't work as the query string, I would like to learn about the differences. Thank you!

Related

My Request Body is so long. How do you handle it while doing API testing via Cypress

My request body for an endpoint is so long:
1st question: I read that we can use some request.body.js file for storing our request body and then call it where ever we need it. But unfortunately, I could not find any sample framework/tutorial to learn it.
2nd question: in my project the properties of the request body (especially names of properties) are not exactly matching with the response body that is gaven in the Swagger document. What can be the reason? What would be your approach?
I would appreciate it if you could help me to ridd off the question in the best possible way. Thank you!
It's quite straight forward, take a look at this login example:
cy.fixture('users.json').then((userdata) => {
cy.request({
method: 'POST',
url: <auth_url>,
form: true,
body: userdata
});
});
You can export this as cypress function and then have it available in all your test spec files.
users.json file in fixtures folder looks like this:
{
"username": "...",
"password": "..."
}
Hope that answers the first question at least.

Verify Joi validation was added to hapi route

I am reusing a Joi schema in multiple places in my code and I would like to find a clean way to test that my endpoints are assigned the validation schema. This would be helpful since I could verify the schema behaved the way I expect without having to repeat the same series of tests everywhere the schema is used.
If I have a hapi server route:
server.route({
method: POST,
path: 'myUrl',
config: {
validate: {
payload: validation.myJoiValidation,
}
}
})
how would I test that the validation.myJoiValidation object has been assigned to the config.validate.payload element?
I dug down into the hapi request object and found that what I am looking for is located in the request.route.settings.validate.payload._inner.children object, but I really don't want to have to rely on that for what I am trying to do.
If you have a server running in the context of your test, you can get the validation schema being used with:
const schema = server.match('post', 'myUrl').settings.validate.payload;
Schemas can't be directly compared (as with Hoek.deepEqual), but they can be compared by using joi.describe, so:
expect(joi.describe(schema)).to.equal(joi.describe(validation.myValidation));
Or, if you are using mocha/chai I think this would be:
expect(joi.describe(schema)).to.deep.equal(joi.describe(validation.myValidation));
In your unit tests make a request with request or similar package with a payload that doesn't pass the validation. Ensure the response code is a 400.
Example test from a project of mine. It tests a regex Join validation on this route. This uses a small promise wrapper around request called yarp.

GET a website url when routing

Sorry, my vocabulary is very limited, any help clarifying this question is deeply appreciated.
I'm building a server using Nodejs and Express, it has a route like /new/:url. I access the value passed on the url by using req.params.url. This works well for simple strings, like chocolate, however, if I pass a website url, like http://www.google.com, then it won't be routed to /new/:url.
Question: how can I pass a website url and access it with Node/Express?
Edit: I am trying to use the GET method, and apparently a way to solve this problem is through Wildcards/Regex.
Thank you very much for helping!
Use Post method.
Set header "Content-Type" : "application/json"
Set body { "urlblahblah~" : "https://www.google.com" }
Then parse It as JSON in server-side
you can use Javascripts encodeURIComponent, so when you passing to your server on client, you will allsways encode the url, so you can pass it as regular parameter. or as mentioned by Hulk if posting is an options you can pass it as body param as well...
var url = encodeURIComponent("http://some.url/asdasa?asdas=12312")
will result in :
"http%3A%2F%2Fsome.url%2Fasdasa%3Fasdas%3D12312"
which is safe for passing as param
The solution that worked for me was Regex. Instead of routing as /new/:url, I used:
/new/:url(*)
So that if http://www.google.com is given as a parameter:
req.params.url = "http://www.google.com"

nodejs - multiple async http requests

I have just started my journey with nodejs and would like to create a simple nodejs app that needs to:
- first request/get some initial data from via http,
- use received json to do another set of requests (some can be done in parallel, some needs to be executed first and data received will be used to create valid url).
Taking into account that nodejs is asynchronous and based on callbacks, I am wondering what is the best way to achieve this in order to have 'clean code' and not mess up with the code too much.
Thanks for any hints / guidelines, Mark
Maybe check out the Async library. Has a lot of built in functionality that seems to accomplish what you're looking for. Couple of useful ones right off the bat might be "async.waterfall" and "async.map".
async.waterfall
async.map
Agreed that this is subjective, in general the way to go is promises, there are native promises:
Native Promise Docs - MDN
For your particular question, imo, the npm module request-promise offers some great solutions. It is essentially a 'Promisified" version of the request module:
It will allow you to GET/POST/PUT/DELETE and follow up each request with a .then() where you can continue to do more calls like so:
-this code first GETS something from a server, then POSTS something else to that server.
function addUserToAccountName(url, accountName, username, password){
var options = assignUrl(url); // assignUrl is not in this code
request
.get(options) //first get
.auth(username, password)
.then(function(res) {
var id = parseId(res.data, accountName); //parse response
return id;
})
.then(function(id) {
var postOptions = Object.assign(defaultSettings, {url: url + id + '/users'})
request.post(postOptions) // then make a post
.auth(username, password)
.then(function(response) {
//console.log(response);
})
.catch(function(err) {
console.log((err.response.body.message));
})
})
}
You can just keep going with the .then() whatever you return from the previous .then() will be passed in to the function.
Request-Promise

NodeJS http.get with state object in the response

I am struggeling with something that I belive supposed to be quite simple once you know how to do it , I apologize if its already been answered - I have searched throughly and could not find an answer.
In Node JS , I want to perform http.get , in the response parameter, I dont pass a closure but a reference to a function that receive a response in a parameter (that way I can have re usability) but I also want to have a state/data object that will be passed to this response function so I could further handle the transaction - with closures its easy but then I need to copy/paste all the time.
https.get({
host: 'www.****.com',
path: ********
}, this._searchResponseHandler.bind(this));
How can that pleased be achieved ?
Thank you ,
James
You can use bind() to also provide initial arguments to your function (the result of which are called partial functions):
this._searchResponseHandler.bind(this, stateObj)
The signature of the handler would become:
_searchResponseHandler : function(stateObj, res) { ... }

Resources