http-fake-backend
http-fake-backend copied to clipboard
feature: Support for query parameters
Hi. Thows error when url like this
module.exports = SetupEndpoint({
name: 'v1',
urls: [{
params: '/read?cmd=on-enter&pid=1414-414-567-3636',
requests: [{
method: 'GET',
response: '/json-templates/anotherExample.json'
}]
}]
}]
});
Nope. This doesn’t work because hapi, the underlying server framework, handles path parameters different to query parameters. They are not part of the route.
We never needed different responses based on query params. So they aren’t configurable for the fake backend for now. The fake backend is pretty stupid and we don’t care if different query params deliver the same response.
Must say that I’m not sure about adding support for them. I would add support if
- more than one person really needs it
- it won’t add too much complexity to the code base
Just in case
Regarding your example I could imagine to configure the query params like that:
module.exports = SetupEndpoint({
name: 'v1',
urls: [{
params: '/read',
requests: [{
method: 'GET',
response: '/json-templates/anotherExample.json',
query: {
cmd: 'on-enter',
pid: '1414-414-567-3636'
}
}]
}]
});
I’m not sure about the expected behavior. Should it be analogous to the behavior of path params?
That means: http://localhost:8081/api/v1/read?cmd=on-enter&pid=1414-414-567-3636 would be the only successful url whereas the following examples would generate 404 errors:
- http://localhost:8081/api/v1/read
- http://localhost:8081/api/v1/read?cmd=on-enter
- http://localhost:8081/api/v1/read?cmd=on-leave&pid=1414-414-567-3636
- http://localhost:8081/api/v1/read?cmd=on-enter&pid=1414-414-567-3635
More flexibility
So I guess query params should have the same flexibility like path parameters:
module.exports = SetupEndpoint({
name: 'v1',
urls: [{
params: '/read',
requests: [{
method: 'GET',
response: '/json-templates/anotherExample.json',
query: {
cmd: '{cmd}',
pid: '{pid?}'
}
}]
}]
});
That means: http://localhost:8081/api/v1/read would still generate a 404 error whereas the following would be valid urls returning the response:
Hey mischah!
We need support for query parameters! 🙂 It would be very useful if you implement what you have proposed.
Many thanks in Advance, Anuj
Hi Mischah,
I am using your project to mock backend and focus on my frontend work. Can you please implement query parameters in the urls if you get some time?
Thank you, Jeevan
Hej @noobg1 @anujshankar @boochamoocha,
challenge accepted. I just pushed a refactoring to master which hopefully improves maintainability and is a good start for adding this feature.
Can’t promise anything right now because of a constraint I mentioned before: I don’t want to add too much bloat the code base to implement a feature we (the project owners) don’t need.
… but I’m going to tackle this within the next couple of days.
Cheers, Michael
Thanks @mischah! Looking forward and excited about this.
Hey Michael!
We have our own implementation of handling query params for http-fake-server.
Details of the implementation:
- Created a mapURLs file which maps the APIs to the respective JSON responses.
- Checking if any query params were present in the query and if it endpoint matches in the hash map then we return the JSON response as mentioned in the hash map.
So basically if a user needs to handle query params then he/she just has to:
- Create route till the path params.
- Create a entry in the mapURLs file with the ‘endpoint(with query params): json file’
Example:
Contents of mapURLs.js
const urlMaps = {
'/api/offer/{number}?filteredby=abc’: '/json-templates/abc.json',
'/api/offer/{number}?filteredby=xyz’: '/json-templates/xyz.json'
};
Changes in the setup.js
const createRoutes = function (url) {
const params = url.params || '';
url.requests.forEach((proposedRequest) => {
const method = proposedRequest.method || 'GET';
const supportedMethod = {
method,
path: path + params,
handler: function (request, reply) {
// Added logic for picking up the mapped urls for understanding query parameters
let response, mapPath = path + params + '?';
const obj = request.query;
if (Object.keys(obj).length !== 0) {
Object.keys(obj).forEach((key) => {
mapPath += key + '=' + obj[key] + '&';
});
mapPath = mapPath.slice(0, -1);
}
console.log(mapPath, mapUrls.hasOwnProperty(mapPath));
if ( mapUrls.hasOwnProperty(mapPath)) {
response = require('../../..' + mapUrls[mapPath]);
console.log('resp');
return reply(response);
}
// End
else if (proposedRequest.statusCode && !proposedRequest.response) {
response = Boom.create(proposedRequest.statusCode);
}
else if (settings.statusCode && !proposedRequest.statusCode) {
response = Boom.create(settings.statusCode);
}
else {
server.log('info', 'Received payload:' + JSON.stringify(request.payload));
if (typeof proposedRequest.response === 'string') {
response = require('../../..' + proposedRequest.response);
}
else {
response = proposedRequest.response;
}
}
if (proposedRequest.statusCode && proposedRequest.response) {
return reply(response).code(proposedRequest.statusCode);
}
return reply(response);
}
};
routes.push(supportedMethod);
});
Any suggestions to improve this approach?
Thanks, Anuj Shankar
Any news? I wasn't able to get the version of @anujshankar up and running... :-/
The only news is, that this one isn’t on the top of my priority list. Just because we still don’t need this feature. Therefore I wont make any promises about implementing it.
But I'm open for a PR :octocat:
Sorry for the folks needing this 😕
Cheers, Michael