Implement an API-first Go rewrite with local engine adapters, upstream fallback, and Nix-based tooling so searches can run without matching the original UI while preserving response compatibility. Made-with: Cursor
76 lines
3 KiB
Markdown
76 lines
3 KiB
Markdown
## gosearch (SearXNG rewrite in Go)
|
|
|
|
This repository contains a standalone Go HTTP service that implements a SearXNG-compatible
|
|
API-first `/search` endpoint and proxies unported engines to an upstream SearXNG instance.
|
|
|
|
### Endpoints
|
|
|
|
- `GET /healthz` -> `OK`
|
|
- `GET|POST /search`
|
|
- Required form/body parameter: `q`
|
|
- Optional: `format` (`json` | `csv` | `rss`; default: `json`)
|
|
|
|
### Supported `format=...`
|
|
|
|
- `json`: SearXNG-style JSON response (`query`, `number_of_results`, `results`, `answers`, `corrections`, `infoboxes`, `suggestions`, `unresponsive_engines`)
|
|
- `csv`: CSV with header `title,url,content,host,engine,score,type`
|
|
- `rss`: RSS 2.0 feed based on the `opensearch_response_rss.xml` template fields
|
|
|
|
### Request parameters
|
|
|
|
The server accepts SearXNG form parameters (both `GET` query string and `POST` form-encoded):
|
|
|
|
- `q` (required): search query
|
|
- `format` (optional): `json`/`csv`/`rss`
|
|
- `pageno` (optional, default `1`): positive integer
|
|
- `safesearch` (optional, default `0`): integer `0..2`
|
|
- `time_range` (optional): `day|week|month|year` (or omitted/`None`)
|
|
- `timeout_limit` (optional): float, seconds (or omitted/`None`)
|
|
- `language` (optional, default `auto`): `auto` or a BCP-47-ish language code
|
|
- `engines` (optional): comma-separated engine names (e.g. `wikipedia,arxiv`)
|
|
- `categories` / `category_<name>` (optional): used for selecting the initial ported subset
|
|
- `engine_data-<engine>-<key>=<value>` (optional): per-engine custom parameters
|
|
|
|
### Environment variables
|
|
|
|
- `PORT` (optional, default `8080`)
|
|
- `UPSTREAM_SEARXNG_URL` (optional for now, but required if you expect unported engines)
|
|
- When set, unported engines are proxied to `${UPSTREAM_SEARXNG_URL}/search` with `format=json`.
|
|
- `LOCAL_PORTED_ENGINES` (optional, default `wikipedia,arxiv,crossref,braveapi,qwant`)
|
|
- Controls which engine names are executed locally (Go-native adapters).
|
|
- `HTTP_TIMEOUT` (optional, default `10s`)
|
|
- Timeout for both local engine API calls and upstream proxy calls.
|
|
- Brave Search API:
|
|
- `BRAVE_API_KEY` (optional): enables the `braveapi` engine when set
|
|
- `BRAVE_ACCESS_TOKEN` (optional): if set, requests must include a token
|
|
(header `Authorization: Bearer <token>`, `X-Search-Token`, `X-Brave-Access-Token`, or form field `token`)
|
|
|
|
### Ported vs proxied strategy
|
|
|
|
1. The service plans which engines should run locally vs upstream using `LOCAL_PORTED_ENGINES`.
|
|
2. It executes local ported engines using Go-native adapters:
|
|
- `wikipedia`, `arxiv`, `crossref`
|
|
3. Any remaining requested engines are proxied to upstream SearXNG (`format=json`).
|
|
4. Responses are merged:
|
|
- `results` are de-duplicated by `engine|title|url`
|
|
- `suggestions`/`corrections` are treated as sets
|
|
- other arrays are concatenated
|
|
|
|
### Running with Nix
|
|
|
|
This repo uses `flake.nix` to provide the Go toolchain.
|
|
|
|
```bash
|
|
nix develop
|
|
go test ./...
|
|
go run ./cmd/searxng-go
|
|
```
|
|
|
|
Example:
|
|
|
|
```bash
|
|
export UPSTREAM_SEARXNG_URL="http://127.0.0.1:8888"
|
|
export PORT="8080"
|
|
nix develop -c go run ./cmd/searxng-go
|
|
```
|
|
|