Skip to content
Prev Previous commit
Next Next commit
docs: Revamp docs, add streaming subscriptions guide, and add navigat…
…ion links
  • Loading branch information
erict875 committed Oct 5, 2025
commit 643539c4abce09c6f906c0ad9f96ffa7c996d8d2
40 changes: 10 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,24 @@

See [docs/GETTING_STARTED.md](docs/GETTING_STARTED.md) for installation and usage instructions.

For a quick API walkthrough, see [`docs/howto/use-nostr-java-api.md`](docs/howto/use-nostr-java-api.md).
## Documentation

See [`docs/CODEBASE_OVERVIEW.md`](docs/CODEBASE_OVERVIEW.md) for details about running tests and contributing.
- Docs index: [docs/README.md](docs/README.md) — quick entry point to all guides and references.
- Getting started: [docs/GETTING_STARTED.md](docs/GETTING_STARTED.md) — install via Maven/Gradle and build from source.
- API how‑to: [docs/howto/use-nostr-java-api.md](docs/howto/use-nostr-java-api.md) — create, sign, and publish basic events.
- Streaming subscriptions: [docs/howto/streaming-subscriptions.md](docs/howto/streaming-subscriptions.md) — open and manage long‑lived, non‑blocking subscriptions.
- Custom events how‑to: [docs/howto/custom-events.md](docs/howto/custom-events.md) — define, sign, and send custom event types.
- API reference: [docs/reference/nostr-java-api.md](docs/reference/nostr-java-api.md) — classes, key methods, and short examples.
- Extending events: [docs/explanation/extending-events.md](docs/explanation/extending-events.md) — guidance for extending the event model.
- Codebase overview and contributing: [docs/CODEBASE_OVERVIEW.md](docs/CODEBASE_OVERVIEW.md) — layout, testing, and contribution workflow.

## Examples
Examples are located in the [`nostr-java-examples`](./nostr-java-examples) module.

- [`SpringSubscriptionExample`](nostr-java-examples/src/main/java/nostr/examples/SpringSubscriptionExample.java)
shows how to open a non-blocking `NostrSpringWebSocketClient` subscription and close it after a
fixed duration.

## Streaming subscriptions

The client and API layers expose a non-blocking streaming API for long-lived subscriptions. Use
`NostrSpringWebSocketClient.subscribe` to open a REQ subscription and receive relay messages via a
callback:

```java
Filters filters = new Filters(new KindFilter<>(Kind.TEXT_NOTE));
AutoCloseable subscription =
client.subscribe(
filters,
"example-subscription",
message -> {
// handle EVENT/NOTICE payloads on your own executor to avoid blocking the socket thread
},
error -> log.warn("Subscription error", error));

// ... keep the subscription open while processing events ...

subscription.close(); // sends CLOSE to the relay and releases the underlying WebSocket
```

Subscriptions must be closed by the caller to ensure a CLOSE frame is sent to the relay and to free
the dedicated WebSocket connection created for the REQ. Callbacks run on the WebSocket thread; for
high-throughput feeds, hand off work to a queue or executor to provide backpressure and keep the
socket responsive.


## Supported NIPs
The API currently implements the following [NIPs](https://github.com/nostr-protocol/nips):
- [NIP-1](https://github.com/nostr-protocol/nips/blob/master/01.md) - Basic protocol flow description
Expand Down
2 changes: 2 additions & 0 deletions docs/CODEBASE_OVERVIEW.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Codebase Overview

Navigation: [Docs index](README.md) · [Getting started](GETTING_STARTED.md) · [API how‑to](howto/use-nostr-java-api.md) · [API reference](reference/nostr-java-api.md)

This document provides an overview of the project structure and instructions for building and testing the modules.

## Module layout
Expand Down
3 changes: 2 additions & 1 deletion docs/GETTING_STARTED.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Getting Started

Navigation: [Docs index](README.md) · [API how‑to](howto/use-nostr-java-api.md) · [Streaming subscriptions](howto/streaming-subscriptions.md) · [API reference](reference/nostr-java-api.md) · [Codebase overview](CODEBASE_OVERVIEW.md)

## Prerequisites
- Maven
- Java 21+
Expand Down Expand Up @@ -48,4 +50,3 @@ dependencies {
Replace `[VERSION]` with the latest release number from the [releases page](https://github.com/tcheeric/nostr-java/releases).

Examples are available in the [`nostr-java-examples`](../nostr-java-examples) module.

16 changes: 16 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Documentation Index

Quick links to the most relevant guides and references.

- Getting Started
- [GETTING_STARTED.md](GETTING_STARTED.md) — install and consume via Maven/Gradle
- How‑to Guides
- [howto/use-nostr-java-api.md](howto/use-nostr-java-api.md) — create, sign, and publish events
- [howto/streaming-subscriptions.md](howto/streaming-subscriptions.md) — open and manage long‑lived subscriptions
- [howto/custom-events.md](howto/custom-events.md) — build and send custom events
- Reference
- [reference/nostr-java-api.md](reference/nostr-java-api.md) — classes, key methods, and examples
- Explanation
- [explanation/extending-events.md](explanation/extending-events.md) — extend the event model
- Project
- [CODEBASE_OVERVIEW.md](CODEBASE_OVERVIEW.md) — codebase layout, testing, contributing
2 changes: 2 additions & 0 deletions docs/explanation/extending-events.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Extending Events

Navigation: [Docs index](../README.md) · [API how‑to](../howto/use-nostr-java-api.md) · [Custom events](../howto/custom-events.md) · [API reference](../reference/nostr-java-api.md)

This project uses factories and registries to make it easy to introduce new event types while keeping core classes stable.

## Factory and Registry Overview
Expand Down
2 changes: 2 additions & 0 deletions docs/howto/custom-events.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Custom Nostr Events

Navigation: [Docs index](../README.md) · [Getting started](../GETTING_STARTED.md) · [API how‑to](use-nostr-java-api.md) · [Streaming subscriptions](streaming-subscriptions.md) · [API reference](../reference/nostr-java-api.md)

This guide shows how to construct and publish a Nostr event with a non-standard `kind` using **nostr-java**.

## Background
Expand Down
83 changes: 83 additions & 0 deletions docs/howto/streaming-subscriptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Streaming Subscriptions

Navigation: [Docs index](../README.md) · [Getting started](../GETTING_STARTED.md) · [API how‑to](use-nostr-java-api.md) · [Custom events](custom-events.md) · [API reference](../reference/nostr-java-api.md)

This guide explains how to open and manage long‑lived, non‑blocking subscriptions to Nostr relays
using the `nostr-java` API. It covers lifecycle, concurrency/backpressure, multiple relays, and
error handling.

## Overview

- Use `NostrSpringWebSocketClient.subscribe` to open a REQ subscription that streams relay messages
to your callback.
- The method returns immediately with an `AutoCloseable`. Calling `close()` sends a `CLOSE` to the
relay(s) and frees the underlying WebSocket resource(s).
- Callbacks run on the WebSocket thread; offload heavy work to your own executor/queue to keep the
socket responsive.

## Quick start

```java
import java.util.Map;
import nostr.api.NostrSpringWebSocketClient;
import nostr.base.Kind;
import nostr.event.filter.Filters;
import nostr.event.filter.KindFilter;

Map<String, String> relays = Map.of("local", "wss://relay.example");

NostrSpringWebSocketClient client = new NostrSpringWebSocketClient().setRelays(relays);

Filters filters = new Filters(new KindFilter<>(Kind.TEXT_NOTE));

AutoCloseable subscription = client.subscribe(
filters,
"example-subscription",
message -> {
// Handle EVENT/EOSE/NOTICE payloads here. Offload if heavy.
},
error -> {
// Log/report errors. Consider retry or metrics.
}
);

// ... keep the subscription open while processing events ...

subscription.close(); // sends CLOSE and releases resources
client.close(); // closes any remaining relay connections
```

See a runnable example in [../../nostr-java-examples/src/main/java/nostr/examples/SpringSubscriptionExample.java](../../nostr-java-examples/src/main/java/nostr/examples/SpringSubscriptionExample.java).

## Lifecycle and closing

- Each `subscribe` call opens a dedicated WebSocket per relay. Keep the handle while you need the
stream and call `close()` when done.
- Always close subscriptions to ensure a `CLOSE` frame is sent to the relay and resources are freed.
- After `close()`, no further messages will be delivered to your listener.

## Concurrency and backpressure

- Message callbacks execute on the WebSocket thread; avoid blocking. If processing may block, hand
off to a separate executor or queue.
- For high‑throughput feeds, consider batching or asynchronous processing to prevent socket stalls.

## Multiple relays

- When multiple relays are configured via `setRelays`, the client opens one WebSocket per relay and
fans out the same REQ. Your listener receives messages from all configured relays.
- Include an identifier (e.g., relay name/URL) in logs/metrics if you need per‑relay visibility.

## Error handling

- Provide an `errorListener` to capture exceptions raised during subscription or message handling.
- Consider transient vs. fatal errors. You can implement retry logic at the application level if
desired.

## Related API

- Client: `nostr-java-api/src/main/java/nostr/api/NostrSpringWebSocketClient.java`
- WebSocket wrapper: `nostr-java-client/src/main/java/nostr/client/springwebsocket/SpringWebSocketClient.java`
- Interface: `nostr-java-client/src/main/java/nostr/client/springwebsocket/WebSocketClientIF.java`

For method signatures and additional details, see the API reference: [../reference/nostr-java-api.md](../reference/nostr-java-api.md).
5 changes: 5 additions & 0 deletions docs/howto/use-nostr-java-api.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Using the nostr-java API

Navigation: [Docs index](../README.md) · [Getting started](../GETTING_STARTED.md) · [Streaming subscriptions](streaming-subscriptions.md) · [Custom events](custom-events.md) · [API reference](../reference/nostr-java-api.md)

This guide shows how to set up the library and publish a basic [Nostr](https://github.com/nostr-protocol/nips) event.

## Minimal setup
Expand Down Expand Up @@ -42,3 +44,6 @@ public class QuickStart {
- [`NIP01.createTextNoteEvent`](../../nostr-java-api/src/main/java/nostr/api/NIP01.java)
- [`EventNostr.sign`](../../nostr-java-api/src/main/java/nostr/api/EventNostr.java)
- [`EventNostr.send`](../../nostr-java-api/src/main/java/nostr/api/EventNostr.java)

### Next steps
- Streaming, lifecycle, and backpressure: [streaming-subscriptions.md](streaming-subscriptions.md)
9 changes: 6 additions & 3 deletions docs/reference/nostr-java-api.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Nostr Java API Reference

Navigation: [Docs index](../README.md) · [Getting started](../GETTING_STARTED.md) · [API how‑to](../howto/use-nostr-java-api.md) · [Streaming subscriptions](../howto/streaming-subscriptions.md) · [Custom events](../howto/custom-events.md)

This document provides an overview of the public API exposed by the `nostr-java` modules. It lists the major classes, configuration objects and their key method signatures, and shows brief examples of how to use them. Where applicable, links to related [Nostr Improvement Proposals (NIPs)](https://github.com/nostr-protocol/nips) are provided.

## Identity (`nostr-java-id`)
Expand Down Expand Up @@ -129,9 +131,10 @@ public void close()
`subscribe` opens a dedicated WebSocket per relay, returns immediately, and streams raw relay
messages to the provided listener. The returned `AutoCloseable` sends a `CLOSE` command and releases
resources when invoked. Because callbacks execute on the WebSocket thread, delegate heavy
processing to another executor to avoid stalling inbound traffic. The
[`SpringSubscriptionExample`](../../nostr-java-examples/src/main/java/nostr/examples/SpringSubscriptionExample.java)
demonstrates how to open a subscription and close it after a fixed duration.
processing to another executor to avoid stalling inbound traffic.

- How‑to guide: [../howto/streaming-subscriptions.md](../howto/streaming-subscriptions.md)
- Example: [../../nostr-java-examples/src/main/java/nostr/examples/SpringSubscriptionExample.java](../../nostr-java-examples/src/main/java/nostr/examples/SpringSubscriptionExample.java)

### Configuration
- `RetryConfig` – enables Spring Retry support.
Expand Down