orcid

package
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 22, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package orcid is a Go client for the ORCID public API (https://pub.orcid.org/v3.0). It resolves ORCID iDs to person records and searches by name for a picker UI.

Example:

c, _ := orcid.New()
p, err := c.Lookup(ctx, "0000-0002-1825-0097")

See package config for construction options and the top-level Normalize and SanitizeSearchTerm helpers.

Auth: the two endpoints this package uses (personal-details, expanded-search) are on the public API host and require no credentials. If per-app rate limits are ever needed, a client credential can be added via a future Option without changing call sites — user OAuth is not required for read-public data.

LIFT-TO-SFLIB / STANDALONE CANDIDATE. This package is written self-contained (no reach into hive-internal state, no singleton) so it can migrate into sflib or graduate to its own repository as an independent ORCID client library.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotFound     = errors.New("orcid: not found")
	ErrInvalidID    = errors.New("orcid: invalid iD")
	ErrRateLimited  = errors.New("orcid: rate limited")
	ErrBadRequest   = errors.New("orcid: bad request")
	ErrUnauthorized = errors.New("orcid: unauthorized")
	ErrServer       = errors.New("orcid: server error")
	ErrConfig       = errors.New("orcid: config error")
)

Sentinel errors for cheap matching with errors.Is. The concrete error struct types (e.g. NotFoundError) carry structured detail; use errors.As to reach it.

Functions

func Normalize

func Normalize(s string) (string, error)

Normalize accepts any of "0000-0002-1825-0097", "https://orcid.org/0000-0002-1825-0097", "0000000218250097", or mixed-case URLs, and returns the canonical dashed form.

Returns *InvalidIDError (which matches ErrInvalidID via errors.Is) when the length, character set, or MOD 11-2 checksum is wrong.

func SanitizeSearchTerm

func SanitizeSearchTerm(s string) string

SanitizeSearchTerm strips characters that the ORCID Solr-backed search grammar treats as operators (`+ - && || ! ( ) { } [ ] ^ " ~ * ? : \ /`) from an untrusted string, making it safe to splice into a Client.Search query without letting a caller inject additional clauses.

The ORCID search does not document a per-character escape mechanism with wide client-library support, so injection safety here relies on stripping rather than escaping — a user-supplied literal ":" cannot be represented inside a query term.

Types

type BadRequestError

type BadRequestError struct {
	Message  string
	Endpoint string
}

BadRequestError wraps a 400 from ORCID, usually caused by a malformed search query. Message holds the server-supplied explanation when present. Matches ErrBadRequest via errors.Is.

func (*BadRequestError) Error

func (e *BadRequestError) Error() string

Error implements the error interface.

func (*BadRequestError) Is

func (e *BadRequestError) Is(target error) bool

Is reports whether target is ErrBadRequest.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the ORCID client. Concurrent-safe. Instantiate with New.

func New

func New(opts ...config.Option) (*Client, error)

New constructs a Client from the supplied options. Returns *ConfigError (matching ErrConfig) when the resolved BaseURL uses http:// on a non-loopback host without OptAllowInsecure.

func (*Client) LastRateLimit

func (c *Client) LastRateLimit() RateLimit

LastRateLimit returns the most recent rate-limit snapshot from the server. Zero-valued until the first successful request completes.

func (*Client) Lookup

func (c *Client) Lookup(ctx context.Context, orcid string) (*Person, error)

Lookup fetches the personal-details record for orcid. Accepts the canonical dashed form or an orcid.org URL; extra whitespace is trimmed. Returns *InvalidIDError (matching ErrInvalidID) for syntactic problems and *NotFoundError (matching ErrNotFound) when the iD is well-formed but unknown to ORCID.

func (*Client) Search

func (c *Client) Search(
	ctx context.Context, query string, opts *SearchOptions,
) ([]Hit, error)

Search runs the ORCID expanded-search against the free-text query and returns matching hits. The query grammar is Solr-style — fielded terms like "family-name:Smith AND given-names:Jane" are legal; an unqualified string matches across name, keyword, and email fields.

Empty query returns (nil, nil) rather than "everyone." Passing a nil opts is equivalent to a zero-valued struct.

For untrusted input inside a query term, wrap the term with SanitizeSearchTerm to strip Solr operator characters.

type ConfigError

type ConfigError struct {
	Msg string
}

ConfigError is returned by client construction when its inputs don't add up (e.g., an http:// BaseURL without OptAllowInsecure). Matches ErrConfig via errors.Is.

func (*ConfigError) Error

func (e *ConfigError) Error() string

Error implements the error interface.

func (*ConfigError) Is

func (e *ConfigError) Is(target error) bool

Is reports whether target is ErrConfig.

type Hit

type Hit struct {
	ORCID       string
	GivenNames  string
	FamilyName  string
	CreditName  string
	Institution string
}

Hit is one match from expanded-search. Institution carries the top affiliation ORCID returned (may be empty); a picker UI displays it alongside the name to disambiguate people who share names.

type InvalidIDError

type InvalidIDError struct {
	Input  string
	Reason string
}

InvalidIDError is returned when an input string is not a syntactically valid ORCID iD (wrong length, wrong character set, or MOD 11-2 checksum mismatch). Matches ErrInvalidID via errors.Is.

func (*InvalidIDError) Error

func (e *InvalidIDError) Error() string

Error implements the error interface.

func (*InvalidIDError) Is

func (e *InvalidIDError) Is(target error) bool

Is reports whether target is ErrInvalidID.

type NotFoundError

type NotFoundError struct {
	ID       string
	Endpoint string
}

NotFoundError is returned for HTTP 404s from ORCID. It matches ErrNotFound via errors.Is.

func (*NotFoundError) Error

func (e *NotFoundError) Error() string

Error implements the error interface.

func (*NotFoundError) Is

func (e *NotFoundError) Is(target error) bool

Is reports whether target is ErrNotFound.

type Person

type Person struct {
	// ORCID is the normalized 19-char form (four dash-separated groups
	// of four, e.g. "0000-0002-1825-0097").
	ORCID string
	// GivenNames — the "given-names" field on the ORCID record.
	GivenNames string
	// FamilyName — the "family-name" field on the ORCID record.
	FamilyName string
	// CreditName — the researcher's preferred citation form when they
	// have set one. Empty when unset; callers should fall back to
	// "GivenNames FamilyName".
	CreditName string
}

Person is a resolved ORCID record. All string fields are best-effort: public records may hide any of them, in which case they arrive empty.

func (Person) DisplayName

func (p Person) DisplayName() string

DisplayName returns the credit name when set, else "given family", else whichever half is present, else the raw ORCID iD.

type RateLimit

type RateLimit struct {
	Limit     int
	Remaining int
	ResetAt   time.Time
	// Observed is the wall-clock time at which this snapshot was taken.
	Observed time.Time
}

RateLimit is the most recent rate-limit snapshot the server sent back. Zero-valued until a request completes. The ORCID public API does not currently expose the granular X-RateLimit-* headers that some other services do; when the server omits them, the fields stay zero.

type RateLimitedError

type RateLimitedError struct {
	RetryAfter time.Duration
	Body       string
}

RateLimitedError is returned when ORCID responds with 429. RetryAfter carries the parsed Retry-After header value (zero if absent or unparseable). Matches ErrRateLimited via errors.Is.

func (*RateLimitedError) Error

func (e *RateLimitedError) Error() string

Error implements the error interface.

func (*RateLimitedError) Is

func (e *RateLimitedError) Is(target error) bool

Is reports whether target is ErrRateLimited.

type SearchOptions

type SearchOptions struct {
	// Rows is the requested page size. Clamped to [1, 200]; zero uses
	// the default (20). ORCID currently caps expanded-search at 200
	// rows per request.
	Rows int
	// Start is the zero-based offset into the result set for
	// pagination. Combine with Rows to walk larger result sets.
	Start int
}

SearchOptions controls what Client.Search returns. Zero-value is legal — Rows defaults to 20, Start to 0.

type ServerError

type ServerError struct {
	Status int
	Body   string
}

ServerError represents a 5xx from ORCID. Callers may retry with backoff. Matches ErrServer via errors.Is.

func (*ServerError) Error

func (e *ServerError) Error() string

Error implements the error interface.

func (*ServerError) Is

func (e *ServerError) Is(target error) bool

Is reports whether target is ErrServer.

type UnauthorizedError

type UnauthorizedError struct {
	Message string
	Status  int
}

UnauthorizedError covers 401 and 403. The public API endpoints used by Client.Lookup and Client.Search do not require credentials, so this typically indicates a record whose visibility is restricted (401), or an IP-level block (403). Matches ErrUnauthorized via errors.Is.

func (*UnauthorizedError) Error

func (e *UnauthorizedError) Error() string

Error implements the error interface.

func (*UnauthorizedError) Is

func (e *UnauthorizedError) Is(target error) bool

Is reports whether target is ErrUnauthorized.

Directories

Path Synopsis
Package config holds the Config and its functional Option setters used to construct an orcid Client.
Package config holds the Config and its functional Option setters used to construct an orcid Client.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL