Skip to content

Latest commit

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Newsdata.io logo

Newsdata.io Java SDK

Maven CentralCIJavaLicenseOpenAPI

Official Java client (SDK) for the Newsdata.io News API. Wraps every endpoint (latest, archive, sources, crypto, market, count, crypto/count, market/count) with client-side parameter validation, automatic retries with exponential backoff, lazy Stream-based pagination, and a typed exception hierarchy.

Built on Java 17's built-in java.net.http.HttpClient — the only runtime dependency is Jackson for JSON. Thread-safe.

Installation

Maven

<dependency>
<groupId>io.newsdata</groupId>
<artifactId>newsdataapi</artifactId>
<version>0.1.0</version>
</dependency>

Gradle (Kotlin DSL)

implementation("io.newsdata:newsdataapi:0.1.0")

Gradle (Groovy DSL)

implementation 'io.newsdata:newsdataapi:0.1.0'

Quickstart

importio.newsdata.api.*;
importjava.util.List;
NewsDataApiClientclient = NewsDataApiClient.builder()
.apiKey(System.getenv("NEWSDATA_API_KEY"))
.build();
NewsdataResponseresp = client.latest(Params.of()
.with("q", "bitcoin")
.with("country", List.of("us", "gb"))
.with("language", List.of("en")));
for (Articlearticle : resp.articles(client.objectMapper())) {
System.out.println(article.title() + " - " + article.link());
}

Endpoints

MethodEndpointNotes
client.latest(params)/1/latestReal-time news
client.archive(params)/1/archiveHistorical news
client.sources(params)/1/sourcesAvailable sources (single page)
client.crypto(params)/1/cryptoCryptocurrency news
client.market(params)/1/marketMarket / financial news
client.count(params)/1/countAggregate counts (requires from_date, to_date)
client.cryptoCount(params)/1/crypto/countAggregate crypto counts
client.marketCount(params)/1/market/countAggregate market counts

params is a Map<String, Object>. Use the bundled Params helper for fluent construction — null values are dropped automatically so you can chain optional fields without if-guards. Values may be String, Number, Boolean, or Collection<String> (sent comma-joined). Parameter names are case-insensitive — qInTitle and qintitle are equivalent.

Pagination

Two helpers — both work for every endpoint except sources:

// 1) scrollAll: follow nextPage and return one merged response.NewsdataResponseall = client.scrollAll(
Endpoint.LATEST,
Params.of().with("q", "news"),
200); // maxResults; 0 = no cap// 2) paginate: lazy Stream<NewsdataResponse>, one page at a time.// Composes with .limit, .takeWhile, .filter, etc.client.paginate(Endpoint.LATEST, Params.of().with("q", "news"))
.limit(5)
.forEach(page -> process(page.articles(client.objectMapper())));

Raw query

client.latest(Params.of().with("rawQuery", "q=bitcoin&country=us&language=en"));

rawQuery is mutually exclusive with every other parameter and is parsed and validated against the endpoint's allowed keys before the request leaves.

Client-side validation

A NewsdataValidationException is thrown — before any HTTP request — when:

  • a parameter is not accepted by that endpoint;
  • mutually-exclusive parameters are set together — q/qInTitle/qInMeta, country/excludecountry, category/excludecategory, language/excludelanguage, domain/domainurl/excludedomain;
  • size is outside 1–50;
  • sentiment_score is set without sentiment;
  • a count endpoint is missing from_date or to_date.

Booleans for full_content, image, video, and removeduplicate are coerced to "1"/"0".

Error handling

All SDK exceptions extend RuntimeException, so they don't pollute method signatures with throws clauses. Catch by type to react to specific failures:

importio.newsdata.api.exception.*;
try {
client.latest(Params.of().with("q", "news"));
} catch (NewsdataValidationExceptione) {
// bad parameter — e.param()
} catch (NewsdataAuthExceptione) {
// 401 / 403
} catch (NewsdataRateLimitExceptione) {
// 429 — e.retryAfter() (seconds)
} catch (NewsdataServerExceptione) {
// 5xx
} catch (NewsdataApiExceptione) {
// other API errors — e.statusCode(), e.responseBody()
} catch (NewsdataNetworkExceptione) {
// I/O, timeout, interrupted — e.getCause()
}

Hierarchy:

NewsdataException (extends RuntimeException)
├── NewsdataValidationException (.param())
├── NewsdataApiException (.statusCode(), .responseBody())
│ ├── NewsdataAuthException (401 / 403)
│ ├── NewsdataRateLimitException (429; .retryAfter())
│ └── NewsdataServerException (5xx)
└── NewsdataNetworkException (.getCause())

Configuration

NewsDataApiClientclient = NewsDataApiClient.builder()
.apiKey(apiKey)
.timeout(Duration.ofSeconds(30)) // per-request
.maxRetries(5) // 1 = no retry
.retryBackoff(Duration.ofSeconds(2)) // base, exponential
.retryBackoffMax(Duration.ofSeconds(60)) // cap on a single sleep
.paginationDelay(Duration.ofSeconds(1))
.baseUrl("https://staging.example/api/1/") // staging / proxy
.includeHeaders(true) // attach response headers
.httpClient(myCustomHttpClient) // proxies, mTLS, etc.
.logger((level, msg) -> System.out.println(level + ": " + msg))
.build();

Retries cover network errors, HTTP 429, and 5xx. 429 honours the Retry-After header (integer seconds or HTTP-date); otherwise backoff is exponential. Auth (401/403) and other 4xx errors are never retried. The API key is redacted from URLs passed to the logger.

Concurrency

NewsDataApiClient is thread-safe — share one instance across your application. The underlying HttpClient reuses connections.

Development

mvn -B verify # compile + run the unit suite (33 tests, no API key needed)
mvn -B test# tests only

The test suite uses Java's built-in com.sun.net.httpserver.HttpServer as a local mock — no WireMock, no network, no external test dep.

Releasing to Maven Central

Releases are automated via .github/workflows/publish.yml — push a v-prefixed tag whose number matches pom.xml's <version> and the workflow signs, uploads, and publishes.

# bump <version> in pom.xml first
git commit -am "Bump to 0.0.2"
git tag -a v0.0.2 -m "v0.0.2"
git push origin main v0.0.2 # tag push fires publish.yml

One-time setup before the first release

Maven Central is the heaviest of the registries to wire up — it predates OIDC trusted publishing and requires GPG-signed artifacts. The good news: you do this once.

1. Register the io.newsdata namespace

  • Sign up at https://central.sonatype.com/.
  • Account → Add Namespace → enter io.newsdata.
  • Verify by adding the displayed TXT record to newsdata.io's DNS. Propagation typically takes minutes; longer for stubborn DNS providers.

2. Create a user token (for the publish workflow)

On https://central.sonatype.com/accountGenerate User Token → copy the token name and token password (you can't see them again).

3. Generate a GPG key

gpg --gen-key # interactive; default RSA 3072 is fine
gpg --list-secret-keys --keyid-format LONG # note the key ID (after sec rsa3072/)
gpg --keyserver keys.openpgp.org --send-keys <KEY_ID># upload public key
gpg --export-secret-keys --armor <KEY_ID>> private.key # this file goes into GitHub

4. Store secrets on GitHub

Repo Settings → Secrets and variablesActionsNew repository secret:

Secret nameValue
MAVEN_USERNAMEthe user-token name from step 2
MAVEN_PASSWORDthe user-token password from step 2
GPG_PRIVATE_KEYthe full contents of private.key from step 3 (including -----BEGIN PGP PRIVATE KEY BLOCK----- lines)
GPG_PASSPHRASEthe passphrase you set in step 3

Then delete private.key from your machine.

5. First publish

Push a tag (git push origin v0.0.2). The workflow:

  1. Verifies the tag matches <version> in pom.xml.
  2. Runs mvn verify (all tests).
  3. Runs mvn -Prelease deploy — signs every artifact (jar, sources, javadoc, pom) with your GPG key and uploads via the central-publishing-maven-plugin.
  4. With autoPublish=true set in the release profile, the deployment is released directly. (For a manual approval gate, set autoPublish=false and approve on https://central.sonatype.com/publishing.)

Artifacts appear on Maven Central indexes within ~10–30 minutes after a successful workflow run, then in the public search within 1–4 hours.

Why no OIDC trusted publishing (yet)?

Unlike npm, PyPI, and pub.dev, the Sonatype Central Portal doesn't yet support tokenless GitHub Actions publishing via OIDC — it's on their roadmap. Until then, the user-token + GPG-signing flow above is the supported path.

Related libraries

Official Newsdata.io clients across languages and runtimes:

Also see free news datasets for ML / NLP work.

License

MIT

About

Official Java SDK for the Newsdata.io News API — typed methods for real-time, historical, crypto, and market news with validation, retries, and typed errors.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages