Skip to content

newsdataapi/newsdata-go-client

Repository files navigation

Newsdata.io Go Client

Go Reference CI Go License

Official Go client 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, scroll/paginate helpers, and a typed error hierarchy. Idiomatic Go: context.Context-aware, no external runtime dependencies, safe for concurrent use.

Installation

go get github.com/newsdataapi/newsdata-go-client@latest

Go modules pull the package straight from GitHub — no separate registry to configure.

Quickstart

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/newsdataapi/newsdata-go-client"
)

func main() {
    client, err := newsdataapi.NewClient(os.Getenv("NEWSDATA_API_KEY"))
    if err != nil {
        log.Fatal(err)
    }

    resp, err := client.Latest(context.Background(), newsdataapi.Params{
        "q":        "bitcoin",
        "country":  []string{"us", "gb"},
        "language": "en",
    })
    if err != nil {
        log.Fatal(err)
    }

    articles, _ := resp.Articles()
    for _, a := range articles {
        fmt.Println(a.Title, "-", a.Link)
    }
}

Endpoints

Method Endpoint Notes
client.Latest(ctx, params) /1/latest Real-time news
client.Archive(ctx, params) /1/archive Historical news
client.Sources(ctx, params) /1/sources Available sources (single page)
client.Crypto(ctx, params) /1/crypto Cryptocurrency news
client.Market(ctx, params) /1/market Market / financial news
client.Count(ctx, params) /1/count Aggregate counts (requires from_date, to_date)
client.CryptoCount(ctx, params) /1/crypto/count Aggregate crypto counts
client.MarketCount(ctx, params) /1/market/count Aggregate market counts

Every value in Params may be a string, a []string (sent comma-joined), a bool, an int, a float64, or *bool / *float64 if you need to distinguish "unset" from a zero value. Parameter names are case-insensitive — qInTitle and qintitle are equivalent.

Pagination

Two helpers; both take an endpoint constant (EndpointLatest, EndpointArchive, …):

// 1) ScrollAll: follow nextPage cursors, return one merged Response.
all, err := client.ScrollAll(ctx, newsdataapi.EndpointLatest,
    newsdataapi.Params{"q": "news"}, 200)

articles, _ := all.Articles() // all 200 in one slice

// 2) Paginate: callback per page. Return false from yield to stop early.
err = client.Paginate(ctx, newsdataapi.EndpointLatest,
    newsdataapi.Params{"q": "news"},
    func(page *newsdataapi.Response, err error) bool {
        if err != nil {
            return false
        }
        arts, _ := page.Articles()
        process(arts)
        return true
    })

Raw query

resp, err := client.Latest(ctx, newsdataapi.Params{
    "rawQuery": "q=bitcoin&country=us&language=en",
})

rawQuery is mutually exclusive with all other parameters and is validated against the endpoint's allowed keys before the request is sent.

Client-side validation

Before any request leaves the process, parameters are validated and a typed *NewsdataValidationError is returned (no API quota spent) 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 errors satisfy the typed hierarchy and play nicely with errors.As and errors.Is:

import "errors"

var (
    ve *newsdataapi.NewsdataValidationError
    ae *newsdataapi.NewsdataAuthError
    rl *newsdataapi.NewsdataRateLimitError
    se *newsdataapi.NewsdataServerError
    ne *newsdataapi.NewsdataNetworkError
    api *newsdataapi.NewsdataAPIError
)

switch {
case errors.As(err, &ve): /* invalid parameter: ve.Param, ve.Message */
case errors.As(err, &ae): /* 401 / 403: ae.StatusCode */
case errors.As(err, &rl): /* 429: rl.RetryAfter (seconds) */
case errors.As(err, &se): /* 5xx */
case errors.As(err, &ne): /* network/timeout/cancellation: ne.Err */
case errors.As(err, &api): /* other API errors: api.StatusCode, api.Message */
}

Hierarchy:

NewsdataError                       (catch-all base)
NewsdataValidationError             (.Param, .Message)
NewsdataAPIError                    (.StatusCode, .Message, .ResponseBody)
├── NewsdataAuthError               (401 / 403)
├── NewsdataRateLimitError          (429; .RetryAfter)
└── NewsdataServerError             (5xx)
NewsdataNetworkError                (.Err)

Configuration

client, err := newsdataapi.NewClient(apiKey,
    newsdataapi.WithTimeout(30 * time.Second),         // per-request
    newsdataapi.WithMaxRetries(5),                     // 1 = no retry
    newsdataapi.WithRetryBackoff(2 * time.Second),     // base, exponential
    newsdataapi.WithRetryBackoffMax(60 * time.Second), // cap on a single sleep
    newsdataapi.WithPaginationDelay(time.Second),
    newsdataapi.WithBaseURL("https://staging.example/api/1/"),
    newsdataapi.WithHTTPClient(myCustomClient),        // proxies / mTLS
    newsdataapi.WithIncludeHeaders(true),              // attach Response.ResponseHeaders
    newsdataapi.WithLogger(myLogger),                  // any Info(msg)/Warn(msg) value
)

Retries cover network errors, HTTP 429, and 5xx responses. 429 honours the Retry-After header (integer seconds or HTTP-date); otherwise the wait is exponential. Auth and other 4xx errors are never retried. context.Context cancellation interrupts retries immediately — passing a cancelled or deadlined context returns a NewsdataNetworkError wrapping context.Canceled or context.DeadlineExceeded.

Concurrency

Client is safe for concurrent use by multiple goroutines.

Development

go test -race ./...                # full unit suite (no API key required)
go vet ./...
go build ./examples/...

The test suite uses net/http/httptest to mock the API end-to-end — no network access required. 30 tests cover the validator, request loop, retry behaviour, scroll + paginate, error mapping, and API-key redaction.

License

MIT

About

Official Go client (SDK) for the Newsdata.io News API — fetch real-time, historical, crypto & stock-market news with validation, retries, and typed errors.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages