{"id":27280956,"url":"https://github.com/posit-dev/plumber2","last_synced_at":"2025-05-07T11:59:00.586Z","repository":{"id":286760023,"uuid":"940040631","full_name":"posit-dev/plumber2","owner":"posit-dev","description":"Easy and Powerful Webservers in R","archived":false,"fork":false,"pushed_at":"2025-04-22T16:00:06.000Z","size":5182,"stargazers_count":58,"open_issues_count":10,"forks_count":4,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-05-07T11:58:50.406Z","etag":null,"topics":["rstats","rstats-package","webapi"],"latest_commit_sha":null,"homepage":"https://posit-dev.github.io/plumber2/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/posit-dev.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","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,"zenodo":null}},"created_at":"2025-02-27T14:17:04.000Z","updated_at":"2025-05-02T15:48:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"7720bb01-522d-47bb-839c-60ef7eaea0e5","html_url":"https://github.com/posit-dev/plumber2","commit_stats":null,"previous_names":["posit-dev/plumber2"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posit-dev%2Fplumber2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posit-dev%2Fplumber2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posit-dev%2Fplumber2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posit-dev%2Fplumber2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/posit-dev","download_url":"https://codeload.github.com/posit-dev/plumber2/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252873974,"owners_count":21817711,"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","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":["rstats","rstats-package","webapi"],"created_at":"2025-04-11T18:01:44.689Z","updated_at":"2025-05-07T11:59:00.568Z","avatar_url":"https://github.com/posit-dev.png","language":"R","readme":"---\noutput: github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\"\n)\n```\n\n# plumber2\n\n\u003c!-- badges: start --\u003e\n[![R-CMD-check](https://github.com/posit-dev/plumber2/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/posit-dev/plumber2/actions/workflows/R-CMD-check.yaml)\n[![Codecov test coverage](https://codecov.io/gh/posit-dev/plumber2/graph/badge.svg)](https://app.codecov.io/gh/posit-dev/plumber2)\n\u003c!-- badges: end --\u003e\n\nThis is a complete rewrite of [plumber](https://www.rplumber.io). The\npurpose of the rewrite is to take everything we’ve learned from plumber,\nshed the bad decision that you inevitably make over the course of\ndevelopment, and start from scratch.\n\nYou’ll find that plumber2 is very similar to plumber in a lot of ways,\nbut diverts in key areas, resulting in API incompatibility between the\ntwo packages. Because of this you may need to update your plumber APIs\nif switching to plumber2.\n\n## Installation\n\nplumber2 is still a work in progress, and it is recommended to only use it to\nexperiment and get familiarity with the future direction of plumber APIs. If you\nwish to try it out you can install the development version from GitHub using\n[pak](https://pak.r-lib.org):\n\n```r\npak::pak(\"posit-dev/plumber2\")\n```\n\n## Feedback\n\nAt this point in the development feedback is crucial. If you do decide to try\nout plumber2, please share your experience, both good and bad, and ask questions\nas it informs us about where to spend more time with documentation.\n\n## Hello World\n\nBelow is a simple \"hello world\" API written for plumber2 that illustrates some\nof the differences from plumber:\n\n```r\n#* Echo the parameter that was sent in\n#*\n#* @get /echo/\u003cmsg\u003e\n#*\n#* @param msg:string The message to echo back.\n#*\n#* @response 200:{msg:string} A string containing the input message\n#*\nfunction(msg) {\n  list(\n    msg = paste0(\"The message is: '\", msg, \"'\")\n  )\n}\n\n#* Plot out data from the palmer penguins dataset\n#*\n#* @get /plot\n#*\n#* @query spec:enum|Adelie, Chinstrap, Gentoo| If provided, filter the\n#* data to only this species\n#*\n#* @serializer png{width = 700, height = 500}\n#* @serializer jpeg{width = 700, height = 500}\n#*\n#* @async\nfunction(query) {\n  myData \u003c- palmerpenguins::penguins\n  title \u003c- \"All Species\"\n\n  # Filter if the species was specified\n  if (!is.null(query$spec)){\n    title \u003c- paste0(\"Only the '\", query$spec, \"' Species\")\n    myData \u003c- subset(myData, species == query$spec)\n    if (nrow(myData) == 0) {\n      abort_internal_error(\"Missing data for {query$spec}\")\n    }\n  }\n\n  plot(\n    myData$flipper_length_mm,\n    myData$bill_length_mm,\n    main=title,\n    xlab=\"Flipper Length (mm)\",\n    ylab=\"Bill Length (mm)\"\n  )\n}\n```\n\nAbove you can both see some breaking changes and some new features in action.\nThe biggest breaking change is that parameters coming from the path, the query\nstring, and the body are now clearly separated. Only parameters from the path\nare provided as direct arguments to the handler function. Query and body\nparameters are accessible through the `query` and `body` argument respectively.\nAs can be seen above they also use different tags in the documentation.\n\nSpeaking of documentation, the parsing of plumber blocks have been greatly\nimproved. It is now built upon roxygen2, so it follows that convention, allowing\nmultiline tags and defaulting to the first line as title and proceeding untagged\nlines as description. The ability to define input and output types has also been\ngreatly expanded, adding the ability to define nested objects, adding default\nvalues and (as seen above) define enum (factors) to name a few. All input will\nget type checked and default value imputed if missing.\n\nFor the `/plot` handler you can also see that it specifies multiple serializers.\nDoing so will allow the client to request its preferred response format using\nthe `Accept` header. plumber2 will then perform content negotiation to figure\nout the best response format based on what it supports and what the client\nprefers.\n\nLastly, you can see a new tag (one of many) in the `/plot` handler. `@async`\nallows you to convert your handler into an async handler automatically. It is\nstill possible to create an async handler manually by returning a promise, but\nthe new tag significantly simplifies this for the most classic cases. There is\nstill overhead involved in handling requests asynchronously so this is mainly a\ngood idea for longer running handlers, but it is shown here as an example.\n","funding_links":[],"categories":["Backend"],"sub_categories":["API Frameworks"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fposit-dev%2Fplumber2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fposit-dev%2Fplumber2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fposit-dev%2Fplumber2/lists"}