How to Use Hister API Endpoints for Search and Configuration

Hister exposes two public HTTP endpoints—GET /search for executing queries and GET /api/config for retrieving server configuration—both defined in server/api.go and implemented in server/endpoints.go.

The asciimoo/hister repository provides a lightweight search engine with a minimal public API surface. Understanding these Hister API endpoints allows developers to integrate full-text search capabilities and read runtime configuration without authentication. Both endpoints are registered centrally and support modern protocols including WebSocket streaming for real-time results.

Hister Search API Endpoint

The search endpoint provides flexible query execution through both traditional HTTP requests and persistent WebSocket connections.

Endpoint Specification

GET /search serves as the primary interface for document retrieval. According to the source code in server/api.go (lines 77‑82), this route accepts standard HTTP GET requests and operates as a public endpoint requiring no authentication or session tokens.

The endpoint behavior branches based on request parameters:

  • With query parameters: Returns JSON search results immediately
  • Without query parameters: Upgrades the connection to a WebSocket for streaming queries

Implementation Details

In server/endpoints.go, the serveSearch handler orchestrates request processing. The function calls parseSearchQueryParams (defined at lines 32‑44) to extract URL parameters and construct an indexer.Query object. This query builder handles filters, pagination, and semantic search options.

The handler delegates to two specific implementations:

  • serveSearchHTTP: Serializes results as JSON when a q or query parameter is present
  • serveSearchWebSocket: Manages persistent connections for interactive search sessions

HTTP Search Example

Execute a simple JSON search by providing the q parameter:

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

type SearchResult struct {
	Documents []struct {
		Title string `json:"title"`
		URL   string `json:"url"`
	} `json:"documents"`
}

func main() {
	resp, err := http.Get("http://localhost:8080/search?q=golang+openapi")
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	var result SearchResult
	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		panic(err)
	}
	for _, d := range result.Documents {
		fmt.Printf("%s – %s\n", d.Title, d.URL)
	}
}

WebSocket Streaming Example

For real-time updates, omit query parameters to trigger the WebSocket upgrade:

package main

import (
	"encoding/json"
	"log"

	"github.com/gorilla/websocket"
)

func main() {
	ws, _, err := websocket.DefaultDialer.Dial("ws://localhost:8080/search", nil)
	if err != nil {
		log.Fatal(err)
	}
	defer ws.Close()

	query := map[string]string{"text": "hister go"}
	if err := ws.WriteJSON(query); err != nil {
		log.Fatal(err)
	}

	var result map[string]any
	if err := ws.ReadJSON(&result); err != nil {
		log.Fatal(err)
	}
	log.Printf("Results: %+v\n", result)
}

Hister Configuration API Endpoint

The configuration endpoint exposes server capabilities and runtime settings to client applications.

Endpoint Specification

GET /api/config returns a JSON payload containing server metadata, search capabilities, and authentication modes. Located at lines 66‑73 in server/api.go, this endpoint is publicly accessible but CSRF-protected to prevent cross-site request forgery attacks. The response includes a fresh CSRF token for subsequent state-changing operations.

Implementation Details

The serveConfig handler in server/endpoints.go (lines 30‑59) aggregates data from multiple sources:

  • config.Config: Runtime server configuration including base URLs
  • searchschema.CapabilitiesDefinition: Supported search features and semantic search availability
  • Authentication mode: Current auth configuration and hot-key settings

This endpoint enables clients to discover server capabilities dynamically before executing searches.

Configuration Retrieval Example

Fetch the server configuration to discover available features:

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

func main() {
	resp, err := http.Get("http://localhost:8080/api/config")
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	var cfg map[string]any
	if err := json.NewDecoder(resp.Body).Decode(&cfg); err != nil {
		panic(err)
	}
	
	fmt.Println("Base URL:", cfg["baseUrl"])
	fmt.Println("Search URL:", cfg["searchUrl"])
	fmt.Println("Semantic search enabled:", cfg["semanticEnabled"])
}

API Registration and Routing

Both endpoints are registered through the registerEndpoints function in server/endpoints.go (lines 60‑66). This function iterates over the Endpoints slice defined in server/api.go and wires each route to the HTTP multiplexer. This centralized registration pattern ensures consistent middleware application and route management across the application.

Summary

  • GET /search executes full-text queries via JSON or WebSocket, implemented by serveSearch in server/endpoints.go with parameter parsing at lines 32‑44.
  • GET /api/config returns runtime configuration and capabilities via serveConfig, protected by CSRF tokens but requiring no authentication.
  • Both endpoints are defined in the Endpoints slice within server/api.go (lines 66‑82) and registered via registerEndpoints.
  • The search endpoint constructs indexer.Query objects for the underlying search engine, while the config endpoint serializes config.Config and capability definitions.

Frequently Asked Questions

What authentication is required for Hister API endpoints?

Both the /search and /api/config endpoints are public and require no authentication tokens or session cookies. However, the /api/config endpoint enforces CSRF protection, meaning clients must obtain and include a valid CSRF token in headers for any non-GET requests, though simple configuration retrieval works without it.

How does the search endpoint decide between HTTP and WebSocket responses?

The serveSearch handler checks for the presence of q or query URL parameters using parseSearchQueryParams. If parameters exist, the handler calls serveSearchHTTP to return JSON results immediately. If no query parameters are provided, the handler upgrades the connection to a WebSocket via serveSearchWebSocket for streaming interaction.

Where are the API endpoint routes defined in the source code?

The route definitions exist in the Endpoints slice located in server/api.go (lines 66‑73 for configuration, lines 77‑82 for search). The concrete HTTP handlers implementing these routes reside in server/endpoints.go, specifically the serveSearch and serveConfig functions.

Can I use the Hister API from a Go application?

Yes, the repository includes client libraries in client/search.go and client/client.go that wrap these public endpoints. These clients handle HTTP requests, WebSocket connections, and response parsing, providing a programmatic interface to the Hister API endpoints without manual HTTP client configuration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →