Skip to content

Commit

Permalink
Merge pull request #22 from kennedymwavu/20-add-example-on-how-to-par…
Browse files Browse the repository at this point in the history
…se-raw-json

ft: add example on how to parse raw json
  • Loading branch information
kennedymwavu authored Jul 28, 2024
2 parents af19f9d + bd2ffbd commit b47cec1
Show file tree
Hide file tree
Showing 8 changed files with 956 additions and 162 deletions.
5 changes: 5 additions & 0 deletions 13_parse_raw_json/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
nodemon.json
package-lock.json
package.json
.Renviron
33 changes: 33 additions & 0 deletions 13_parse_raw_json/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Parse raw JSON

Say you have an API endpoint that expects raw JSON data. How do you parse that?

This example answers that and is in a way related to the example on [csv & xlsx upload](../11_csv_xlsx_upload).

This is a simple example revolving around how you can select columns and filter
rows in the `iris` dataset when the request body is something like this:

```json
{
"cols": ["Sepal.Length", "Petal.Width", "Species"],
"species": ["virginica", "setosa"]
}
```

# Run API

1. `cd` into the `13_parse_raw_json/` dir:

```bash
cd 13_parse_raw_json/
```
1. Fire up R and restore package dependencies:

```r
renv::restore()
```
1. `server.R` is the entry point. Run this command in the terminal to start the API:

```bash
Rscript server.R
```
47 changes: 47 additions & 0 deletions 13_parse_raw_json/server.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
box::use(
ambiorix[Ambiorix],
webutils[parse_http],
)

#' Handle POST at '/'
#'
#' @param req Request object.
#' @param res Response object.
#' @return `res$json()`
#' @export
home_post <- \(req, res) {
content_type <- req$CONTENT_TYPE
body <- req$rook.input$read()

if (length(body) == 0L) {
response <- list(
code = 400L,
msg = "Invalid request"
)

return(
res$set_status(400L)$json(response)
)
}

postdata <- parse_http(body, content_type)

# filter & select as necessary:
row_inds <- iris$Species %in% postdata$species
col_inds <- colnames(iris) %in% postdata$cols
data <- iris[row_inds, col_inds, drop = FALSE]

response <- list(
code = 200L,
msg = "success",
data = data
)

res$json(response)
}

app <- Ambiorix$new(port = 3000, host = "127.0.0.1")

app$
post("/", home_post)$
start()
24 changes: 23 additions & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ <h1 class="title">Documentation</h1>
<!-- margin-sidebar -->
<div id="quarto-margin-sidebar" class="sidebar margin-sidebar">

<h5 class="quarto-listing-category-title">Categories</h5><div class="quarto-listing-category category-default"><div class="category" data-category="">All <span class="quarto-category-count">(13)</span></div><div class="category" data-category="00_getting_started">00_getting_started <span class="quarto-category-count">(1)</span></div><div class="category" data-category="01_hello_world">01_hello_world <span class="quarto-category-count">(1)</span></div><div class="category" data-category="02_static_files">02_static_files <span class="quarto-category-count">(1)</span></div><div class="category" data-category="03_basic_routing">03_basic_routing <span class="quarto-category-count">(1)</span></div><div class="category" data-category="04_simple_json_api">04_simple_json_api <span class="quarto-category-count">(1)</span></div><div class="category" data-category="05_router">05_router <span class="quarto-category-count">(1)</span></div><div class="category" data-category="06_multi_router">06_multi_router <span class="quarto-category-count">(1)</span></div><div class="category" data-category="07_dynamic_rendering">07_dynamic_rendering <span class="quarto-category-count">(1)</span></div><div class="category" data-category="08_datatables">08_datatables <span class="quarto-category-count">(1)</span></div><div class="category" data-category="09_goals">09_goals <span class="quarto-category-count">(1)</span></div><div class="category" data-category="10_live_reloading">10_live_reloading <span class="quarto-category-count">(1)</span></div><div class="category" data-category="11_csv_xlsx_upload">11_csv_xlsx_upload <span class="quarto-category-count">(1)</span></div><div class="category" data-category="frontend_for_09_goals">frontend_for_09_goals <span class="quarto-category-count">(1)</span></div></div></div>
<h5 class="quarto-listing-category-title">Categories</h5><div class="quarto-listing-category category-default"><div class="category" data-category="">All <span class="quarto-category-count">(14)</span></div><div class="category" data-category="00_getting_started">00_getting_started <span class="quarto-category-count">(1)</span></div><div class="category" data-category="01_hello_world">01_hello_world <span class="quarto-category-count">(1)</span></div><div class="category" data-category="02_static_files">02_static_files <span class="quarto-category-count">(1)</span></div><div class="category" data-category="03_basic_routing">03_basic_routing <span class="quarto-category-count">(1)</span></div><div class="category" data-category="04_simple_json_api">04_simple_json_api <span class="quarto-category-count">(1)</span></div><div class="category" data-category="05_router">05_router <span class="quarto-category-count">(1)</span></div><div class="category" data-category="06_multi_router">06_multi_router <span class="quarto-category-count">(1)</span></div><div class="category" data-category="07_dynamic_rendering">07_dynamic_rendering <span class="quarto-category-count">(1)</span></div><div class="category" data-category="08_datatables">08_datatables <span class="quarto-category-count">(1)</span></div><div class="category" data-category="09_goals">09_goals <span class="quarto-category-count">(1)</span></div><div class="category" data-category="10_live_reloading">10_live_reloading <span class="quarto-category-count">(1)</span></div><div class="category" data-category="11_csv_xlsx_upload">11_csv_xlsx_upload <span class="quarto-category-count">(1)</span></div><div class="category" data-category="frontend_for_09_goals">frontend_for_09_goals <span class="quarto-category-count">(1)</span></div><div class="category" data-category="parse_raw_json">parse_raw_json <span class="quarto-category-count">(1)</span></div></div></div>
<!-- main -->
<main class="content quarto-banner-title-block column-page-left" id="quarto-document-content">

Expand Down Expand Up @@ -513,6 +513,28 @@ <h5 class="no-anchor card-title listing-title">
</div>
</a>
</div>
<div class="g-col-1" data-index="13" data-categories="parse_raw_json" data-listing-date-sort="1722200400000" data-listing-file-modified-sort="1722207755512" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="1" data-listing-word-count-sort="118">
<a href="./posts/13_parse_raw_json/index.html" class="quarto-grid-link">
<div class="quarto-grid-item card h-100 card-left">
<div class="card-body post-contents">
<h5 class="no-anchor card-title listing-title">
13: parse raw json
</h5>
<div class="card-subtitle listing-subtitle">
how to parse raw json in requests
</div>
<div class="card-attribution card-text-small justify">
<div class="listing-author">
Kennedy Mwavu
</div>
<div class="listing-date">
Jul 29, 2024
</div>
</div>
</div>
</div>
</a>
</div>
</div>
<div class="listing-no-matching d-none">
No matching items
Expand Down
3 changes: 2 additions & 1 deletion docs/listings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"/posts/09_goals/index.html",
"/posts/10_live_reloading/index.html",
"/posts/11_csv_xlsx_upload/index.html",
"/posts/12_frontend_for_09_goals/index.html"
"/posts/12_frontend_for_09_goals/index.html",
"/posts/13_parse_raw_json/index.html"
]
}
]
Loading

0 comments on commit b47cec1

Please sign in to comment.