I am using mithril in an IoT framework. I am trying to isolate the front-end development from backend API implementation tasks. In jQuery, I have used jQuery-mockjax and a similar mechanism in Angular. What I understand is that those libraries intercept ajax function call an appropriately respond with data that are setup using $.mockjax (or similar functions)
The mechanism recommended here https://groups.google.com/forum/#!topic/mithriljs/FzpCPMfauf0, does not give the flexibility to implement this. There is no easy way to use mock for a selected few APIs.
After looking through the code, I realized is, to implement this, I need to get access to the ‘ajax’ function (or just the XHR processing section), so that it can be overridden using my own implementation that can mock selected APIs. The problem is that ajax is a local function in the library. If it is exposed as m.ajax, my library can override it and get the functionality I need.
My question is, is there a better way to achieve the same? If you have done similar things please share.
My code structure will be something like this:
// in mithril-mockjax.js, implements mockjax function
m.mockjax = function (options) { … }
// in app-api-mocks.js
m.mockjax({
method: GET,
url: /sessions/123,
response: { …}
});
m.mockjax({
method: POST,
url: /sessions,
data: {},
response: { … }
});
The above two files are inserted in the page when I am in the development mode. The rest of the code remains the same.
You can do this by either mocking m.request by monkey-patching it or you add a layer of abstraction between m.request and your code that you are then able to mock away.
Related
I am writing a headless solution for a WordPress website and noticed that for one particular endpoint, I need to authenticate to pull some data that will be used publicly. But, I'm concerned that where I'm using it will expose it to the web.
In my store/index.js I use the nuxtServerInit action method to execute some actions and I pass them some objects they need to fulfill their tasks:
async nuxtServerInit ({ dispatch }, { $axios, app }) {
await dispatch('initialize', { $axios, app })
},
$axios is passed because it will be used to query the API, and app is passed to help build the options to authenticate the request.
Is this a security vulnerability in Nuxt SSR? I think it is. If so, where are the only valid areas you can use secrets? asyncData ()?
If you're using SSR, you can use the privateRuntimeConfig runtime object and pass your secret in the nuxt.config.js file
export default {
privateRuntimeConfig: {
apiSecret: process.env.API_SECRET
}
}
If you read the documentation of nuxtServerInit, you can see that
Vuex action that is called only on server-side to pre-populate the store
Since this method is server-side only, you can use apiSecret (in my example) and it should be totally fine security-wise.
PS: Keep in mind that everything beyond what is generated on the server (hence, with NodeJS or nuxtServerInit) is "public". So your VueJS's client code lifecycle hooks are public: mounted(), fetch(), asyncData() because they will be visible on your browser's devtools.
Also, should your endpoint be that critical? If so, nuxtServerInit is the good way to go. If you need to fetch some more data in a "private way", you'll need to proxy it through some backend to hide the sensitive info and retrieve only the useful public data.
I am pretty much new to Node JS. We do have a requirement to use the request header from router to model class.
Let us assume an simple router
router.ts
router.delete(
'/sample/:id',
validateRequest(),
async function (req: Request, res: Response, next: NextFunction) {
try {
const solution: string = req.header('Some Header Value') || '';
await Controller.someMethods(req.params.id, solution);
return res.json(new HttpResponse('SUCCESS', {}, {}));
} catch (err) {
return next(err);
}
},
);
This is our router, Here we should be able to read "solution" in controller, service, and model classes. Right now we have passed this as an argument to different components. Is there any better approach to read the header value which is in the current request scope?
Similarly using components in spring framework, or sesison management or any other better approach other than passing the header value as an argument at each component level.
regards
Eresh
TL; DR; There is no other way than just mapping it manually.
Express is quite minimalistic so we don't such abstractions as Spring, the truth is that Node.js is different from Java. In Java we spawn a thread per request, so every request has a single thread. Whereas Node.js is async and single-threaded, so multiple requests share the same thread so you need to pass the values down your calls because there is no out-of-the-box solution on storing global values for a request.
If you want to have an access to the headers somewhere inside an application you could build a system that does so. The first step is to add the middleware that stores the headers in service with a unique ID associated with it and somehow passes this ID down the road. Then whenever you know the ID you could call the service to get the data for you, though you still will need to pass the ID down the road. I think you should not care about that, and that is okay. I would refactor your code in a way that a Controller methods access req and res then all the logic of working with these objects will be incapsulated here, whereas the service layer will expect raw data that know nothing about the transport layer that controllers operate with. Thus you can call services from another service, because they know nothing about the request and response.
FWIW, if you need a better framework use Nest.js, it is great and advanced, also it uses decorators (in a way similar to annotations in Spring). For instance you could just inject the header value as a call argument for your method in the following way #Header("some-header") solution: string
Best regards.
I’m always coding backend api’s and I don’t really get how express does its bidding with my code. I know what the request and response objects offer, I just don’t understand how they come to be.
This simplified code for instance:
exports.getBlurts = function() {
return function(req, res) {
// build query…
qry.exec(function(err, results) {
res.json(results);
}
});
}
}
Then I’d call in one of my routes:
app.get('/getblurts/, middleware.requireUser, routes.api.blurtapi.getBlurts());
I get that the function is called upon the route request. It’s very abstract to me though and I don’t understand the when, where, or how as it pertains to the req\res params being injected.
For instance. I use a CMS that modifies the request object by adding a user property, which is then available globally on all requests made whether ajax or otherwise, making it easy at all times to determine if a user is logged in.
Are the req and res objects just pre-cooked by express but allow freedom for them to be modified to your needs? When are they actually 'built'
At its heart express is actually using node's default http-module and passing the express-application as a callback to the http.createServer-function. The request and response objects are populated at that point, i.e. from node itself for every incoming connection. See the nodeJS documentation for more details regarding node's http-module and what req/res are.
You might want to check out express' source code which shows how the express application is passed as a callback to http.createServer.
https://github.com/expressjs/express/blob/master/lib/request.js and https://github.com/expressjs/express/blob/master/lib/response.js show how node's request/response are extended by express specific functions.
I need to make an API request to an external API using an API Key. I know how to make this API request in React by writing a onSubmit function. But since I have an API key that I want to keep a secret I am going to write a simple Node app to house env variables.
Besides messing around in node this is my first production experience with Node and I am wondering if my thought process is correct and if not, the better way to do this.
Most of this question will be pseudo code since I haven't started with the Node portion yet.
The idea is that from within the React component it would call the Node app who in turn would call the external API.
React -> Node -> External API
So the React component would be something like so:
handleSubmit: function() {
var data = this.refs.testData.getDomNode().value;
$.ajax({
url: '/my-node-endpoint',
dataType: 'json',
type: 'POST',
data: { test: data },
success: function(data) {
// Whatever success call I want to make
}.bind(this)
})
}
And then in my Node app it would like something like this:
app.post('/my-node-endpoint', function(req, res) {
// Store the values we are posting as JSON
// Start the post request
// On End tell the React component everything is ok
// Prosper
});
As always, thanks for any help that is offered.
Your thought process looks right to me.
If the API you are calling is from a different domain, you will have to build a wrapper on your node server like you did here. Unless the external API supports cross-origin requests with no domain restrictions (such as MapBox web services), you will have to do this.
Several improvements to your code:
As far as I know, you can use React.findDOMNode(this.refs.testData).value instead of this.refs.testData.getDomNode().value. getDomNode() is deprecated in v0.13.
For all the AJAX calls, you can use the Store concept in Flux. The store keeps the states of the data, including updating data through AJAX request. In your React UI code, you just need to call the methods of the store, which makes your UI code clean. I usually create a store class myself without using Flux.
Is there a way add data to a couchdb that runs on another domain and get back an response whether the operation was successfully or not? I know couchdb supports jsonp callback but can I add data with this approach?
No, you cannot currently do this. CouchDB's REST API requires a POST or PUT request in order to insert data, but JSONP only supports GET requests. So you can retrieve data from CouchDB across domains, but updates/inserts/deletes won't work.
You can use client-side javascript to make a form to do the POST, direct the output to an iframe, and use cross-window iframe messaging to get the result.
Of course, someone has already made a nice javascript library to do this. Get the code here:
https://github.com/benvinegar/couchdb-xd
Follow the instructions to push it as an additional database on your couchdb server. Then, on any site, include one not in the 'your-couch-server' domain, you can do the following (just try it in the javascript console):
jQuery.getScript(
"http://YOUR-COUCH-SERVER/couchdb-xd/_design/couchdb-xd/couchdb.js",
function() {
Couch.init(
function() {
var s = new Couch.Server('http://YOUR-COUCH-SERVER/');
var d = new Couch.Database(s,'YOURDB');
d.put(
"stackoverflow-test 1",
{ foo: 111, bar: 222 },
function(resp) {
console.log(resp);
}
);
}
)
}
);
The above presumes you have jquery is already loaded on the page. If not, you'll need to add it however you're currently interacting with the other page.
The library only works on modern browsers with window.postMessage() support, though a small patch may eventually allow older browsers to use it via src/hash communication.