Suggestions needed for building R server REST API's that I can call from external app?
Asked Answered
P

2

19

I've seen lots of articles about consuming data in R from other RESTful API services, but I have really struggled to find any articles about the reverse. I'm interested in R being the server, and not the client. I'd like a Node.js app to call a RESTful API of an R-server so I can leverage specific analytical functions such as multi-seasonality forecasting. Anyone have any ideas?

Pileum answered 4/3, 2014 at 18:1 Comment(5)
This is pretty much the most fleshed out option I've seen in this space but there are half a dozen alternatives: opencpu.orgHithermost
Any chance for generic curl interface? as described in the bounty.Jury
Did you even look at the docs for OpenCPU? At the top of the API page, it explicitly states "many of the sections below contain curl examples".Frias
@r2evans, I've played with opencpu a while ago (without success), don't know if it changed much since that time. Anyway I'm looking for a simple code to run in R, to just host the function which I can call with the curl. The examples are perfect, but there is no simple run server from R commands to type in R. If you know, please post as answer, deserved bounty will be yours!Jury
Sorry, the comment about reading the docs was aimed at the comment that asked if it had a generic curl interface. I do think opencpu could fit the bill, though. Though not ideal, opencpu does start a single-process server for testing when you load the library interactively, and it still works remarkably well.Frias
K
21

You can use httpuv to fire up a basic server then handle the GET/POST requests. The following isn't "REST" per se, but it should provide the basic framework:

library(httpuv)
library(RCurl)
library(httr)

app <- list(call=function(req) {

  query <- req$QUERY_STRING
  qs <- httr:::parse_query(gsub("^\\?", "", query))

  status <- 200L
  headers <- list('Content-Type' = 'text/html')

  if (!is.character(query) || identical(query, "")) {
    body <- "\r\n<html><body></body></html>"
  } else {
    body <- sprintf("\r\n<html><body>a=%s</body></html>", qs$a)
  }

  ret <- list(status=status,
              headers=headers,
              body=body)

  return(ret)

})

message("Starting server...")

server <- startServer("127.0.0.1", 8000, app=app)
on.exit(stopServer(server))

while(TRUE) {
  service()
  Sys.sleep(0.001)
}

stopServer(server)

I have the httr and RCurl packages in there since you'll probably end up needing to use some bits of both to parse/format/etc requests & responses.

Kosak answered 9/4, 2015 at 11:43 Comment(0)
I
6

node-rio provides a way to talk to rserve (a TCP/IP server that allows the use of R functions) from node.js.

Here is an example of use (from the documentation):

var rio = require('rio');
rio.evaluate("as.character('Hello World')");
Intoxicate answered 4/3, 2014 at 18:12 Comment(2)
Thanks! I found that later yesterday as well and got the basic evaluate method to work. Having trouble on the sourceAndEvaluate method when I have to pass in variables. Can you help on something as simple as: testFunction <- function(a,b) { return a+b } ? I figured out how to step debugging through it sourcing this function by path, but I can't figure out how to parameterize data IO with the function. Any ideas?Pileum
Sorry, I am not too familiar with the actual working of node js. I mostly just know rserve. I would open up a new question.Intoxicate

© 2022 - 2024 — McMap. All rights reserved.