{"id":14066447,"url":"https://github.com/JfrAziz/r-plumber","last_synced_at":"2025-07-29T23:31:04.874Z","repository":{"id":157792227,"uuid":"629880416","full_name":"JfrAziz/r-plumber","owner":"JfrAziz","description":"Rplumber: Rest API witth R. a boilerplate to setup a new project with R plumber","archived":false,"fork":false,"pushed_at":"2024-06-16T19:53:03.000Z","size":83,"stargazers_count":18,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-16T21:47:25.298Z","etag":null,"topics":["docker","docker-compose","r","r-language","r-plumber","r-programming","rest-api"],"latest_commit_sha":null,"homepage":"https://jafaraziz.com/blog/rest-api-with-r-part-1","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JfrAziz.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-19T08:03:08.000Z","updated_at":"2025-01-22T15:10:54.000Z","dependencies_parsed_at":"2024-02-19T18:24:33.933Z","dependency_job_id":"0a9c5807-984f-4a57-9c89-57bd7a585580","html_url":"https://github.com/JfrAziz/r-plumber","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/JfrAziz/r-plumber","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JfrAziz%2Fr-plumber","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JfrAziz%2Fr-plumber/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JfrAziz%2Fr-plumber/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JfrAziz%2Fr-plumber/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JfrAziz","download_url":"https://codeload.github.com/JfrAziz/r-plumber/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JfrAziz%2Fr-plumber/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267779969,"owners_count":24143200,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-29T02:00:12.549Z","response_time":2574,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","docker-compose","r","r-language","r-plumber","r-programming","rest-api"],"created_at":"2024-08-13T07:05:06.223Z","updated_at":"2025-07-29T23:31:04.587Z","avatar_url":"https://github.com/JfrAziz.png","language":"R","readme":"# R Plumber API Templates\n\n## Features\n\nThis repository is a boilerplate to setup a new project with R plumber. You can use or customize the code provided in this repository for your own purposes. The features included in this templates are:\n\n| Features                   | Implemented | Description                                                                                                                                                                                                     |\n| -------------------------- | :---------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Logging                    |     ✅      | Better way to log any incoming request to stdout and file with `logger` package                                                                                                                                 |\n| Error Handling             |     ✅      | Proper \u0026 simple error handling with custom HTTP Response code                                                                                                                                                   |\n| File Based Routing         |     ✅      | Auto mount route file from `routes` dir with file name based endpoint                                                                                                                                           |\n| Dynamic Filter/Miiddleware |     ✅      | Add custom filter / middleware each mounted route from `routes` dir                                                                                                                                             |\n| Request Validation         |     ✅      | Simple validation mechanism to check incoming request from request body / params, such as required fields, check type (number, boolean, array), check the value in given array, etc.                            |\n| Docker                     |     ✅      | Simplifying apps with docker, for better development, deployment, dependencies management, and scaling                                                                                                          |\n| Parallel Processing        |     ✅      | R only run a request at a time, make it process in parallel with `promises` and `future` packages.                                                                                                              |\n| Testing                    |     ✅      | Testing for endpoints / routes and helper functions with `testthat` and `httr` packages, also use Docker and docker-compose for setting up automated testing. For running in CI / CD, an example also provided. |\n\nThis template comes with built in Environment Variables that you can edit when running it.\n\n| ENV       |   Default   | Description                                                                                    |\n| --------- | :---------: | ---------------------------------------------------------------------------------------------- |\n| `HOST`    | `127.0.0.1` | Host to run Rplumber, use `0.0.0.0` when running it in Docker                                  |\n| `PORT`    |   `8000`    | Which port Rplumber will run                                                                   |\n| `WORKERS` |     `3`     | Number of worker (Rsession) to run parallel processing in Rplumber (including the main worker) |\n\n## How to use it\n\nTo use this templates, you must have Docker installed, I am prefer using docker because it's simple and can run anywhere, just build and run. If you not using docker you can run it manullay from `Rstudio` or any IDE you like by using this command `Rscript app.R` in the project dir, and make sure you have installed all the dependecies / packages before running it.\n\n```bash\ndocker build -t \"r-plumber:latest\" .\n\ndocker run -d --name \"r-plumber\" -e \"HOST=0.0.0.0\" -p 8000:8000 r-plumber:latest\n```\n\n\u003e Note that, if you made changes to your project, you must restart the container or running it again.\n\n### Routing\n\nI am using the term `route` for the `*.R` files in `routes` dir, and `enpoint` for any function inside it. To create a new route or endpoint, just create a `*.R` file in `routes` dir with `roxygen2` like comment or annotation like this.\n\n```r\n# routes/example-route.R\n\n#* Return a message\n#* @param msg The message to echo\n#* @serializer unboxedJSON\n#* @get /\nfunction(msg=\"\") {\n  list(msg = paste0(\"The message is: '\", msg, \"'\"))\n}\n\n#* Return a hello message\n#* @serializer unboxedJSON\n#* @get /hello\nfunction(msg=\"\") {\n  list(msg = 'Hallo from /hello endpoint')\n}\n```\n\nAnd this will generate `GET /example-route/` and `GET /example-route/hello` endpoints. Read more about it from the [docs](https://www.rplumber.io/)\n\n### Filter or Middleware\n\nMiddleware or Filter is the \"same term\" to describe something in beetween before the request come to controller. To use filter, add this following code to your routes.\n\n```r\n# routes/custom-filter/enable.R\n\n#* @plumber\nfunction(pr) {\n  pr %\u003e%\n    pr_filter(\"custom-filter\", function(req, res) {\n      log_info(\"CUSTOM FILTER CALLED\")\n      plumber::forward()\n    })\n}\n```\n\nThe second params is your filter function, you can create it directly or create global function in helpers (but don't forget to import it). Now any endpoint in `/routes/custom-filter/enable.R` will run the filter function, but the other routes doesn't. By using this method, we can use filter as many as we need for each routes.\n\n### Request Validation\n\nWe validate the request using custom function from [`helpers/validator.R`](./helpers/validator.R), you can take a look to the example in this endpoint [`routes/validation.R`](./routes/validation.R)\n\n### Parallel Processing\n\nParallel processing in Rplumber use `future` and `promises` packages, that package will process incoming request in another Rsession called worker. Or if your have enough resources you can run multi container in kubernetes clusters or docker swarms and put load balancer on top of it, to distribute incoming traffict.\n\n![Parallel](./docs/parallel.excalidraw.svg)\n\nWorker only created in one containers, and to use workers add total workers in your env variables and use this method for long process endpoints that takes too much time, so the API can continue processing incoming requests even while working on others. You can add to any endpoint like this\n\n```r\n# routes/task.R\n\n#* slow endpoint with promise\n#* @serializer unboxedJSON\n#* @get /slow-with-promise\nfunction(req, res) {\n  future_promise({\n    # your long procesing task\n    Sys.sleep(10)\n    return(list(message = \"Slow with promise endpoint\"))\n  })\n}\n```\n\n### Testing\n\nThis project use another approach to run testing with `testthat` package. `testthat` used to test R packages, but we used in this project for running the test manually with help of docker and docker-compose. In [`docker-compose.test.yaml`](./docker-compose.test.yaml) we setup 2 services, the API and the test, both using the same docker images. First we run the API then the test. To run this, use this command so after the test completed all the container will be stopped.\n\n```bash\ndocker compose -f \"docker-compose.test.yaml\" up  --abort-on-container-exit --exit-code-from test --attach test\n```\n\nFor running this in CI / CD, an example is provided in this [github-actions](./.github/workflows/test.yml). The result of this test will be printed out in docker-logs\n\nSome of the examples of test case can be found in the form of `test-*.R` files in `test` directory. You can create your own test cases by creating the `test-*.R` files in that directory and follow the [`testthat` documentations](https://testthat.r-lib.org). Note that, `test` prefix is required in file name and the files cannot be located in the subdirectory as `testthat` does not support it yet.\n\n## Deploy\n\nDeploying docker images it’s easy, you can deploy it like other images in Kubernetes, Docker Swarm, Cloud in GCP / AWS, or a VPS.\n\n## Resources\n\nI have blog post about this projects, check it out\n\n- [Project Setup, Logging, and Error Handling](https://jafaraziz.com/blog/rest-api-with-r-part-1/)\n- [Routing and Request Validation](https://jafaraziz.com/blog/rest-api-with-r-part-2/)\n- [Deploy with Docker](https://jafaraziz.com/blog/rest-api-with-r-part-3/)\n- [Testing and CI / CD](https://jafaraziz.com/blog/rest-api-with-r-part-4/)\n- [Parallel Processing and Performance](https://jafaraziz.com/blog/rest-api-with-r-part-5/)\n\n## Last...\n\nHappy coding...\n","funding_links":[],"categories":["R"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJfrAziz%2Fr-plumber","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FJfrAziz%2Fr-plumber","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJfrAziz%2Fr-plumber/lists"}