2017-09-03 50 views
1

我想知道如何使運行終點爲RunKit does如何創建一個正在運行的API端點?

在該RunKit頁面中,它會生成一個與代碼關聯的URL。在瀏覽器中打開該URL將看到代碼定義的response。此外,代碼的更改將實時反映出來。

有誰知道他們是如何實現這一目標的?

我知道在平均堆棧網站中定義一個固定的api。例如,由於以下代碼,可以調用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) 
}) 
+0

謝謝......這是「自動更新」的一部分,我不看他們如何實現... – SoftTimur

+0

我看到......我看到有人使用nodemon。現在,我想知道更多的是他們在觸發自動更新之前將瀏覽器中更新的功能的內容傳遞給'router.get(...)'。 – SoftTimur

回答

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} 
+0

非常感謝您的回覆,並且很抱歉。你所做的就是將所有的函數及其參數存儲在一個哈希對象中,然後根據路由器調用正確的函數。但是,我想要一些更靈活的東西:我想用一個瀏覽器中的用戶輸入的字符串來動態創建一個函數。我猜想需要用JS字符串構造一個函數。 – SoftTimur

+0

我將函數存儲在散列對象中,這意味着如果我支持n個函數,則可以從api端點動態調用它們。該函數的參數直接來自url本身。他們還支持向散列對象添加一個函數的方法,這使得它成爲動態的。我也會嘗試添加。 – TheChetan

+0

如果你可以添加一個由JS String動態構造的函數,那會很好。如果你能確保你的代碼有效,那會很好。 – SoftTimur

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.
還檢查了該SO有關的訊息串創建JS功能:
Is there a way to create a function from a string with javascript?

相關問題