我想知道如何将正在运行的端点设为RunKit does。
在RunKit的该页面中,它会生成与代码关联的URL。在浏览器中打开该URL将看到代码定义的https://myexample.com/api/add/3/5
。此外,代码的更改将实时反映。
有谁知道他们是如何实现这一目标的?
我知道在一个平均堆栈网站中定义一个固定的api。例如,由于以下代码,可以调用router.get('/api/add/:a/:b', function (req, res, next) {
var r = Number(req.params.a) + Number(req.params.b);
res.json(r)
})
。但我不知道如何制作一个可以实时更改其功能的API。
//Validate player 1:
if (!empty($_POST['player1'])) {
$player1 = $_POST['player1'];
$player1_dob = $_POST['player1_dob'];
$player1_grade = $_POST['player1_grade'];
} elseif (!empty($_POST['player1_dob'])) {
echo "You forgot to enter Player 1's date of birth.<br>";
$validate = 'false';
} elseif (!empty($_POST['player1_grade'])) {
echo "You forgot to enter Player 1's grade.<br>";
$validate = 'false';
} else {
$validate = 'true';
}
答案 0 :(得分:1)
Express中间件只是常规的JS功能。
为了使路由具有不断变化的功能,您无需在运行时更改中间件功能,只需更改其行为方式即可。
我会尝试在这里展示一个可能的解决方案 请注意,这只是一个概念验证,而不是生产就绪和/或安全的解决方案。
假设您的网站上有某种在线代码编辑器,允许您的用户编写JS代码并将其保存在您的数据库中。
您可以像这样设置端点路由:
router.get('/endpoint/:id', (req, res) => {
// this id identifies a previously saved code wrote by a user
let id = req.params.id
// NOTE: THIS IS NOT ACTUAL WORKING JS CODE
// fetch the previously saved code from your database as a string
let code = database.getDocumentById(id)
// you can construct an actual JS function form the string, using the `Function()` constructor
let f = Function(code)
// now you can call the function, do whatever you like with it and finally send the user the results
let result = f()
res.send(result)
})
您可能需要为用户提供的代码创建包装函数,并控制将执行的内容以及结果。
P.S。
另请查看关于从字符串创建JS函数的SO帖子:
Is there a way to create a function from a string with javascript?
答案 1 :(得分:0)
基本思想是,创建一个存储为字符串的函数数据库。由于JS允许您使用Function()
构造函数从字符串创建函数,因此您可以根据需要动态生成函数。我提供了一个POST
端点来注册该功能。
var express = require("express");
var app = express();
var bodyParser = require('body-parser');
var router = express.Router();
var mongoose = require('mongoose');
db = mongoose.connect('mongodb://localhost:27017/login1');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
var data = new mongoose.Schema({
"name": String,
"content": String
});
model = mongoose.model("functions", data);
router.post('/create', (req, res) => {
// Insert validation for security and removing duplicates etc.
model.insertMany({"name": req.body.name, "content": req.body.content}).then((d, err) => {
res.status(200).send({'result': "Added"});
});
});
router.get('/:func/*', (req, res) => {
var func = req.params.func;
var args = req.params['0'].split('/');
model.findOne({"name": func}).then((d, err) => {
if (err) {return res.status(404).send({'result': "Error with database"});}
else if (d === null) {return res.status(202).send({'result': "Function not present"});}
var func = Function(d.content);
res.status(200).send({'result': func(...args)});
});
});
app.use("/", router);
var port = process.env.PORT || 3000;
var server = app.listen(port, function() {
console.log('Express server listening on port ' + port);
});
让我们测试一下:
$ node server.js
Express server listening on port 3000
从邮递员或其他终端窗口:
$ curl -X GET "http://localhost:3000/add/1/2/3"
{"result":"Function not present"}
现在让我们注册add
函数(sum of arguments
):
$ curl -X POST "http://localhost:3000/create/" -H "content-type:application/json" -d '{"name": "add", "content": "return [...arguments].reduce( (i, j) => i+=parseInt(j), 0);"}'
{'result': "Added"}
此处注册的功能可能要复杂得多。请记住,您可以使用Agruments变量获取传递给函数的所有参数。
测试它:
$ curl -X GET "http://localhost:3000/add/1/2/3"
{"result": 6}
$ curl -X GET "http://localhost:3000/add/100/3/5/10/9/2"
{"result": 129}