Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mozgiii/sap
Opinionated HTTP server for hosting static files of Single Page Apps from memory with blazing fast speeds
https://github.com/mozgiii/sap
http http-server spa static-file-server static-files static-site web-server
Last synced: 3 months ago
JSON representation
Opinionated HTTP server for hosting static files of Single Page Apps from memory with blazing fast speeds
- Host: GitHub
- URL: https://github.com/mozgiii/sap
- Owner: MOZGIII
- Created: 2024-05-20T05:50:38.000Z (9 months ago)
- Default Branch: master
- Last Pushed: 2024-10-15T19:52:03.000Z (4 months ago)
- Last Synced: 2024-10-17T01:03:39.675Z (4 months ago)
- Topics: http, http-server, spa, static-file-server, static-files, static-site, web-server
- Language: Rust
- Homepage:
- Size: 163 KB
- Stars: 1
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# sap
Opinionated HTTP server for hosting static files of Single Page Apps from memory
with blazing fast speeds.## Goals and non-goals
Goals:
- serve static files
- simple templating to allow injecting ENV-values-based configurations
- easy docker image composition
- sane configuration for select HTTP header values, like CSP and etcNon-goals:
- SSR
- SPA code builds (you can still do this via your own docker stages)
- API proxying (already handled by the reverse proxy / edge)
- HTTPS (already handled by the reverse proxy / edge)## Usage
Using the `onbuild` image:
```dockerfile
FROM ghcr.io/mozgiii/sap:latest-onbuild
```or using the regular image and copying the files manually:
```dockerfile
FROM ghcr.io/mozgiii/sap:latestCOPY . /app
ENV ROOT_DIR=/app
```## Configuration
### Server configuration
All the configuration parameters are set via env vars.
See [`crates/sap/src/main.rs`](crates/sap/src/main.rs) to learn about the available settings.
### SPA configuration
There are two (opinionated) ways for configuring Single Page Applications
with `sap`:1. substituting values from the env variables for the corresponding
JSON object keys in the HTML `script` tag with the `type` attribute set
to `application/spa-cfg` on the `/` route - this is called HTML templating,
and
2. substituting values from the env variables for the corresponding
JSON object keys in the JSON file on the `/config.json` route - this is
called JSON templating.#### General idea
The in both cases we take the JSON object. We iterate over the keys of
the object, we take each key, turn it into `CONSTANT_CASE` add prefix and
check if a env var with this name exists. If it doesn't - the value of the key
is left as it is in the original JSON, but if the env var **is** set - then
we replace the value in JSON with the value of the env var.> [!WARNING]
>
> We require that JSON object used for configuration has only `string` values.
>
> In TypeScript that requirement would look like this:
>
> ```js
> type Config = { [key: string]: string };
> ```#### HTML templating
Here is a simplified example of `index.html` file (used as the root (`/`) route):
```html
{"myKey": "default value"}
```
With `sap` using default SPA configs prefix `APP_` and with
the `APP_MY_KEY` env var set to `override value`, this is what the returned
page body will look like:```html
{"myKey": "override value"}
```
##### Example with Docker (HTML templating)
If we assume that you have a `Dockerfile` like this:
```shell
$ cat Dockerfile
FROM ghcr.io/mozgiii/sap:latest
ENV ROOT_DIR /app
COPY build /app
```and the `index.html` in the `build` directory like this:
```shell
$ cat build/index.html{"myKey": "default value"}
```
we can build the test image like this:
```shell
$ docker build . -t sap-test
...
```At this point we have our app dockerized and ready to run.
```shell
$ docker run --rm -it -p 8080:8080 sap-test
...
2024-01-01T12:34:56.789123Z Successfully applied HTML templating route=/ dir_entry_path="/app/index.html"
...
2024-01-01T12:34:56.789123Z INFO sap: About to start the server addr=0.0.0.0:8080
...
```In another terminal we can run the following command to try it:
```shell
$ curl http://localhost:8080{"myKey": "default value"}
```
The neat thing is that we can change the settings as we please, without
rebuilding the app from source or recreating docker image - just like
it was intended with containers!Continue with stopping the `sap-test` container via `Ctrl+C`...
```shell
C^
... (stopping) ...
$
```... and running with the env var to change the SPA configuration:
```shell
$ docker run --rm -it -p 8080:8080 -e APP_MY_KEY="override value" sap-test
...
2024-01-01T12:34:56.789123Z Successfully applied HTML templating route=/ dir_entry_path="/app/index.html"
...
2024-01-01T12:34:56.789123Z INFO sap: About to start the server addr=0.0.0.0:8080
...
```Then in the other terminal:
```shell
$ curl http://localhost:8080{"myKey": "override value"}
```
Note how the configuration value `myKey` has changed.
##### Usage in the SPA code (HTML templating)
This can be utilized from the SPA with the code like this:
```js
function readConfig() {
const el = document.querySelector("script[type=\"application/spa-cfg\"]");
const configText = el.innerText;
const config = JSON.parse(configText);
return config;
}
```This allows you to get the dynamic configuration without rebuilds. This way also
has a benefit of not involving any `async` or `Promise`s.#### JSON templating
> [!IMPORTANT]
>
> JSON templating in an opt-in, and requires `CONFIG_JSON_TEMPLATING=true` env
> var to be set to work.An example of `config.json` file (with the `/config.json` route):
```json
{"myKey":"default value"}
```With `sap` with `CONFIG_JSON_TEMPLATING=true`, using default SPA configs prefix
`APP_` and with the `APP_MY_KEY` env var set to `override value`, this is what
the returned `/config.json` response body will look like:```json
{"myKey":"override value"}
```##### Example with Docker (JSON templating)
If we assume that you have a `Dockerfile` like this:
```shell
$ cat Dockerfile
FROM ghcr.io/mozgiii/sap:latest
ENV ROOT_DIR /app
COPY build /app
```and the `config.json` in the `build` directory like this:
```shell
$ cat build/config.json
{"myKey":"default value"}
```we can build the test image like this:
```shell
$ docker build . -t sap-test
...
```At this point we have our app dockerized and ready to run.
> Well, technically it is just the config, but you can add the rest of the files
> of your app there as well.```shell
$ docker run --rm -it -p 8080:8080 sap-test
...
2024-01-01T12:34:56.789123Z Successfully applied JSON templating route=/config.json dir_entry_path="/app/config.json"
...
2024-01-01T12:34:56.789123Z INFO sap: About to start the server addr=0.0.0.0:8080
...
```In another terminal we can run the following command to try it:
```shell
$ curl http://localhost:8080/config.json
{"myKey":"default value"}
```The neat thing, just like with HTML templating, is that we can change
the settings as we please, without rebuilding the app from source or recreating
docker image - just like it was intended with containers!Continue with stopping the `sap-test` container via `Ctrl+C`...
```shell
C^
... (stopping) ...
$
```... and running with the env var to change the SPA configuration:
```shell
$ docker run --rm -it -p 8080:8080 -e APP_MY_KEY="override value" sap-test
...
2024-01-01T12:34:56.789123Z Successfully applied JSON templating route=/config.json dir_entry_path="/app/config.json"
...
2024-01-01T12:34:56.789123Z INFO sap: About to start the server addr=0.0.0.0:8080
...
```Then in the other terminal:
```shell
$ curl http://localhost:8080/config.json
{"myKey":"override value"}
```Again, just like with HTML templating, configuration value of the key `myKey`
has changed.##### Usage in the SPA code (JSON templating)
This can be utilized from the SPA with the code like this:
```js
const readConfig = async () => fetch("/config.json").then(res => res.json());
```