How to use `api` and `routes` folder in uibuilder vue3 template?

I am a beginner in node-red and I started node-red a few days ago.
I created a new node by using uibuilder with vue3 template.
But I am not sure how I can use api and routes folders of uibuilder node.
I appreciate you if any guy help me.
Thanks

Hi, sounds like you are jumping in at the deep end. :slight_smile: These are more complex capabilities that most people don't need.

The api folder is there to allow per-instance API's - that's to say, if you have multiple uibuilder nodes in use, the api folder will let you define API's just for that single instance. API's are defined as ExpressJS routes. Documentation. Note that, because this is a fairly sensitive area, it is turned off by default. To turn it on, you need to make a change in your settings.js.

The routes folders allow you to specify server-side routes - URL's - and deliver custom outputs using server-side code. Each route is an ExpressJS middleware function.

From the v6.5 release notes:

  • uibuilder Instance routes/middleware - You can now add ExpressJS routes and other middleware to a single instance of uibuilder (a specific uibuilder node), not just to all nodes. Especially useful if you want to add custom security (login, registration, etc) to just one instance.The new feature lets you specify the sub-url-path, the HTTP method and the callback function. Paths can include wildcards and parameters too. The routes are always added to the instance router which forces them to only ever be sub-url-paths of the specified instance. e.g. if your instance url is test, a route with a path of /foo/:bah will ALWAYS be .../test/foo/.... This is for security. Note that you are responsible for creating unique URL paths, no checking is done and ExpressJS is quite happy to have multiple path handlers but if you provide a terminating response (e.g. res.status(200)) and no next() call, the call stack is obviously terminated. If you include a call to next(), overlapping route callbacks will also be triggered. In that case, make sure you do not do any more res.xxxx() responses otherwise you will get an ERR_HTTP_HEADERS_SENT error.To add route handlers, create 1 or more .js files in the <instanceRoot>/routes/ folder. See the docs for details.What can I do? Authentication, authorisation, http headers, dynamic html changes/additions, js inserts, logging, server-side includes, server-side rendering (e.g. Jade, ...) ...

Note that if you are only using a single instance of uibuilder or if you want to define middleware for all instances, you might find it easier to work with the common middleware for which you can find templated examples in ~./node-red/uibuilder/.common. In there you will also find templates for Socket.IO realtime-data transfer middleware.

Also, if you want to define routes in the front-end rather than at the server (AKA create a Single-Page App - SPA), then you can use the new uibrouter.js library.

Also note that you can, of course, create API's using Node-RED's core http-in/-out nodes though obviously, that wouldn't let you use some of the data built into uibuilder such as the client id.

1 Like

Thank you for your reply.
If you can give me example code for api and routes, it would be great.
Potentially, I want to use /api/sensors api for sensors list, I am going to return json data manually in the api function.

Hmm, not been a lot of call for those so far so I don't know that I have an example to hand. I need to see if I've got any of the old tests ... ah wait, yes I do have the code, not sure about an accompanying flow.

Here is some code for an API:

/** Example uibuilder instance API file with multiple methods
 *  Each method will be applied to `<uibInstanceURL>/api/:something` path
 *  You have to reload Node-RED if you change this file.
 *  It is best to use named functions as shown because it makes debugging URL paths easier when using the uibindex page.
 */
'use strict'

function apiUse(req, res, next) {
    console.log('>> api.js USE >>', req.params)
    next()
}

function apiGet(req, res, next) {
    res.send('Woo Hoo')
    console.log('>> api.js GET >>', req.params)
    next()
}

module.exports = {
    // Must be a valid ExpressJS URI path. It will be appended to the instance URL.
    path: '/api/one/:something',

    // route name='use', path='/api/', route=''
    use: apiUse,

    // route name='bound dispach', path='/api/', route='get:/^\/?$/i'
    get: apiGet,

}

It goes into a file with a *.js name in the api folder.

Here is another example:

/** Example uibuilder instance API file with custom apiSetup()
 */
'use strict'

let uibNode, uibMaster

function api3Get(req, res, next) {
    let contexts = Object.keys(uibMaster.RED.settings.contextStorage)
    contexts = contexts.join(', ')

    res.send(
        `
        <div>
          Node ID: ${uibNode.id}, <br>
          uibuilder root path: ${uibMaster.nodeRoot}, <br>
          Node-RED context stores: [${contexts}]
        </div>
        <h2>Node-RED Settings</h2>
        <pre><code>${JSON.stringify(uibMaster.RED.settings)}</code></pre>
        `
    )

    console.log('>> api3.js GET >>', req.params)
    next()
}

module.exports = {
    // Must be a valid ExpressJS URI path. It will be appended to the instance URL.
    path: '/api/three/',

    apiSetup(node, uib) {
        //console.log('>> api3Setup >>', node.url, '>> node >>', node, '>> uib >>', uib, '<<<<')
        uibNode = node
        uibMaster = uib
    },

    // route name='bound dispach', path='/api/three/', route='get:/^\/?$/i'
    get: api3Get,

}

As you can see, the instance api's use a somewhat simplified ExpressJS structure. the uibNode and uibMaster vars are magic variables that are passed from the parent uibuilder node (I think! I can't actually remember now :grinning: ). Instance API Doc - allowed fn names - you must use the apiSetup function to populate those, you can actually call them anything as you can see in the 2nd example.

1 Like

Thank you so much. It works for me
:+1: :+1: :+1: :+1: :+1:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.