186 lines
6.0 KiB
Markdown
186 lines
6.0 KiB
Markdown
# weatherapi Operations
|
|
|
|
`weatherapi` is a read-only HTTP service. It serves latest weather records from
|
|
Postgres tables populated by `weatherfeeder`; it does not ingest provider data,
|
|
create tables, or run database migrations.
|
|
|
|
## Runtime Model
|
|
|
|
At startup, the executable:
|
|
|
|
1. resolves the config path from `-config`, `WEATHERAPI_CONFIG`, or `config.yml`;
|
|
2. loads feedapi YAML configuration;
|
|
3. opens all configured database handles;
|
|
4. selects the first configured database as the primary weather data store;
|
|
5. registers HTTP endpoints and text templates with feedapi;
|
|
6. starts the HTTP server.
|
|
|
|
See [`docs/cli.md`](cli.md) for invocation details and [`docs/config.md`](config.md)
|
|
for configuration fields.
|
|
|
|
## Prerequisites
|
|
|
|
- A reachable PostgreSQL database.
|
|
- Weatherfeeder-owned weather tables already created and populated.
|
|
- A config file with at least one `databases` entry.
|
|
- The `templates/` directory when `format=text` responses are needed.
|
|
- Network access from the service process or container to Postgres.
|
|
|
|
The first database entry in the config is the only database used for weather
|
|
reads. Additional configured handles may be opened by feedapi, but `weatherapi`
|
|
selects the first entry as primary.
|
|
|
|
## Local Run
|
|
|
|
Use the checked-in local sample only when its database settings match your
|
|
environment:
|
|
|
|
```sh
|
|
go run ./cmd/weatherapi -config config.yml
|
|
```
|
|
|
|
For a local binary:
|
|
|
|
```sh
|
|
go build -o ./weatherapi ./cmd/weatherapi
|
|
./weatherapi -config config.yml
|
|
```
|
|
|
|
Keep the process working directory aligned with `templates.base_dir`. With the
|
|
checked-in config, run from the repository root so `templates` resolves to the
|
|
repository's template directory.
|
|
|
|
## Container Run
|
|
|
|
The Docker image copies these runtime files into `/weatherapi`:
|
|
|
|
- `/weatherapi/weatherapi`
|
|
- `/weatherapi/config.yml`
|
|
- `/weatherapi/templates`
|
|
|
|
The runtime working directory is `/weatherapi`, and the entrypoint is the
|
|
`weatherapi` binary. To use the image's bundled config and templates:
|
|
|
|
```sh
|
|
docker run --rm -p 8080:8080 weatherapi
|
|
```
|
|
|
|
To provide an external config file:
|
|
|
|
```sh
|
|
docker run --rm -p 8080:8080 \
|
|
-v "$PWD/examples/config.production.yml:/weatherapi/config.yml:ro" \
|
|
weatherapi
|
|
```
|
|
|
|
To use a different config path, append the CLI flag:
|
|
|
|
```sh
|
|
docker run --rm -p 8080:8080 \
|
|
-v "$PWD/config.yml:/config/weatherapi.yml:ro" \
|
|
weatherapi -config /config/weatherapi.yml
|
|
```
|
|
|
|
If you mount a custom template directory, make `templates.base_dir` point to the
|
|
mounted path.
|
|
|
|
The repository's Woodpecker image build uses Kaniko and passes private Gitea
|
|
credentials as build arguments so Go can download private modules during the
|
|
build.
|
|
|
|
## Database Dependency
|
|
|
|
`weatherapi` expects weatherfeeder-compatible tables for observations, current
|
|
conditions aggregation, active alerts, forecasts, forecast discussions, and
|
|
weather stories. It only reads those tables.
|
|
|
|
Operational ownership is split:
|
|
|
|
- `weatherfeeder` owns provider polling, normalization, writes, table creation,
|
|
and schema compatibility.
|
|
- PostgreSQL owns durable storage, backups, replication, and restore.
|
|
- `weatherapi` owns serving read-only HTTP responses from the configured
|
|
primary database.
|
|
|
|
When restoring from backup or replacing the database, verify that weatherfeeder
|
|
has resumed writes before treating stale `weatherapi` responses as an API
|
|
problem.
|
|
|
|
## Templates and Text Output
|
|
|
|
JSON and XML responses do not depend on text templates. `format=text` uses the
|
|
template named by each endpoint, with templates stored under `templates.base_dir`.
|
|
|
|
The repository includes templates for all implemented endpoint families:
|
|
observations, current conditions, active alerts, hourly forecasts, narrative
|
|
forecasts, forecast discussions, and weather stories.
|
|
|
|
If text rendering fails or returns an unsupported-format error, verify:
|
|
|
|
- the process can read `templates.base_dir`;
|
|
- expected `*.txt.tmpl` files are present;
|
|
- the requested endpoint supports `format=text`, which all implemented
|
|
endpoints currently do.
|
|
|
|
## Startup and Shutdown
|
|
|
|
Startup failures are fatal and are logged with the prefix `weatherapi failed`.
|
|
Common failure contexts include:
|
|
|
|
- `load config`
|
|
- `config.databases requires at least one entry`
|
|
- `open databases`
|
|
- `select primary database`
|
|
- `build app`
|
|
|
|
The process handles `SIGINT` and `SIGTERM`. Feedapi performs graceful HTTP
|
|
shutdown after the runtime context is canceled. Database close errors during
|
|
shutdown are logged, but they occur after the service has already begun stopping.
|
|
|
|
## Verification
|
|
|
|
There is no dedicated health endpoint in `weatherapi`. Use an implemented read
|
|
endpoint as a practical service check:
|
|
|
|
```sh
|
|
curl -i 'http://localhost:8080/observations?format=json'
|
|
```
|
|
|
|
Interpretation:
|
|
|
|
- `200 OK` with `{"data": null}` means the service is running but no latest
|
|
observation is available.
|
|
- `200 OK` with a populated `data` object means the service and that read path
|
|
are working.
|
|
- `400 Bad Request` indicates request validation, not service health.
|
|
- `406 Not Acceptable` indicates format negotiation.
|
|
- `5xx` indicates a runtime, database, or handler failure.
|
|
|
|
For a broader smoke check, use the requests in
|
|
[`examples/requests.http`](../examples/requests.http).
|
|
|
|
## Logs
|
|
|
|
The executable uses Go's standard logger with date, time, and microseconds.
|
|
Startup and fatal runtime errors are written to standard error. Container
|
|
platforms should collect stdout and stderr from the process.
|
|
|
|
## Backup and Recovery Boundaries
|
|
|
|
Back up and restore PostgreSQL using normal database procedures. `weatherapi`
|
|
has no local durable weather state to back up.
|
|
|
|
After a database restore or failover:
|
|
|
|
1. confirm the configured database is reachable from the service;
|
|
2. confirm weatherfeeder-owned tables exist;
|
|
3. confirm weatherfeeder is writing fresh rows if current data is expected;
|
|
4. restart `weatherapi` if database connection settings changed;
|
|
5. verify with an implemented endpoint such as `/observations`.
|
|
|
|
## Related Docs
|
|
|
|
- [`docs/api.md`](api.md): HTTP contract and error envelope
|
|
- [`docs/config.md`](config.md): configuration reference
|
|
- [`docs/troubleshooting.md`](troubleshooting.md): symptom-oriented fixes
|