Documentation
¶
Index ¶
- Constants
- Variables
- func BatchParseSeq(inputs []string) iter.Seq2[int, Result[Postcode]]
- func ParseSeq(inputs []string) iter.Seq2[Postcode, error]
- type APIError
- type AdministrativeAddress
- type AssembledPostcode
- type AutocompleteResponse
- type AutocompleteSuggestion
- type Client
- func (c *Client) Assemble(ctx context.Context, segs Segments) (*AssembledPostcode, error)
- func (c *Client) Autocomplete(ctx context.Context, query string) (*AutocompleteResponse, error)
- func (c *Client) Disassemble(ctx context.Context, code string) (*Segments, error)
- func (c *Client) Lookup(ctx context.Context, code string, level LookupLevel) (*LookupResponse, error)
- func (c *Client) Nearby(ctx context.Context, params NearbyParams) (*NearbyResponse, error)
- func (c *Client) RateLimit() *RateLimitInfo
- func (c *Client) Reverse(ctx context.Context, params ReverseParams) (*ReverseResponse, error)
- type ClientOption
- func WithAPIKey(key string) ClientOption
- func WithBaseTransport(rt http.RoundTripper) ClientOption
- func WithBaseURL(customURL string) ClientOption
- func WithRateLimitRetry(enabled bool, maxDelay time.Duration) ClientOption
- func WithRetryConfig(cfg RetryConfig) ClientOption
- func WithTelemetry(t Telemetry) ClientOption
- func WithTimeout(d time.Duration) ClientOption
- func WithTransport(rt http.RoundTripper) ClientOption
- type LookupLevel
- type LookupResponse
- type MetricsRecorder
- type NearbyParams
- type NearbyResponse
- type NearbyUnit
- type PointGeometry
- type Postcode
- func (p Postcode) AppendText(b []byte) ([]byte, error)
- func (p Postcode) Area() string
- func (p Postcode) BuildingUnit() string
- func (p Postcode) District() string
- func (p Postcode) Formatted() string
- func (p Postcode) IsZero() bool
- func (p Postcode) LGA() string
- func (p Postcode) MarshalText() ([]byte, error)
- func (p Postcode) Raw() string
- func (p Postcode) State() string
- func (p Postcode) String() string
- func (p *Postcode) UnmarshalText(text []byte) error
- type RateLimitInfo
- type RecentHouseAddress
- type Result
- type RetryConfig
- type RetryTransport
- type ReverseParams
- type ReverseResponse
- type Segments
- type Span
- type Telemetry
- type Tracer
Constants ¶
const (
DefaultBaseURL = "https://api.postcode.gov.ng"
)
Variables ¶
var ( ErrInvalidLength = errors.New("postcode: invalid length, must be exactly 11 alphanumeric characters") ErrInvalidFormat = errors.New("postcode: invalid format structure") )
Functions ¶
func BatchParseSeq ¶
BatchParseSeq yields an iter.Seq2 iterator with slice index and Result wrapper.
Types ¶
type APIError ¶
type APIError struct {
StatusCode int `json:"-"`
Code string `json:"code"`
Message string `json:"message"`
RateLimit *RateLimitInfo `json:"-"`
RetryAfter time.Duration `json:"-"`
}
APIError represents an error returned by the NIPOST Postcode API gateway.
func (*APIError) IsInsufficientCredits ¶
func (*APIError) IsNotFound ¶
func (*APIError) IsRateLimit ¶
func (*APIError) IsUnauthorized ¶
func (*APIError) UnmarshalJSON ¶
UnmarshalJSON handles both the official nested envelope {"error": {"code": ..., "message": ...}} and flat payloads {"code": ..., "message": ...}.
type AdministrativeAddress ¶
type AdministrativeAddress struct {
State string `json:"state,omitempty"`
StateName string `json:"state_name,omitempty"`
LGA string `json:"lga,omitempty"`
LGAName string `json:"lga_name,omitempty"`
District string `json:"district,omitempty"`
DistrictName string `json:"district_name,omitempty"`
Area string `json:"area,omitempty"`
AreaName string `json:"area_name,omitempty"`
Unit string `json:"unit,omitempty"`
Zone string `json:"zone,omitempty"`
LocalityName string `json:"locality_name,omitempty"`
}
AdministrativeAddress details administrative boundaries up to area level (L2+).
type AssembledPostcode ¶
type AssembledPostcode struct {
Postcode string `json:"postcode"` // Canonical: "EK-01-A03-FK-01"
Display string `json:"display"` // Spaced: "EK 01 A03 FK 01"
Compact string `json:"compact"` // Compact: "EK01A03FK01"
}
AssembledPostcode represents the output of POST /v1/assembly/assemble.
type AutocompleteResponse ¶
type AutocompleteResponse struct {
Segment string `json:"segment"`
Suggestions []AutocompleteSuggestion `json:"suggestions"`
}
AutocompleteResponse contains suggestions for the currently active segment.
type AutocompleteSuggestion ¶
AutocompleteSuggestion represents an individual suggestion returned by autocomplete.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
func NewClient ¶
func NewClient(opts ...ClientOption) (*Client, error)
NewClient instantiates a production-tuned HTTP client.
func (*Client) Assemble ¶
Assemble builds canonical, display, and compact postcodes from individual segments.
func (*Client) Autocomplete ¶
Autocomplete retrieves segment-aware suggestions for a partial postcode input (e.g. "EK 01 A").
func (*Client) Disassemble ¶
Disassemble decomposes a postcode string into its 5 structural segments.
func (*Client) Lookup ¶
func (c *Client) Lookup(ctx context.Context, code string, level LookupLevel) (*LookupResponse, error)
Lookup queries the gateway for detailed attributes of a postcode. Level defaults to Level1 (free) if 0 or unspecified.
func (*Client) Nearby ¶
func (c *Client) Nearby(ctx context.Context, params NearbyParams) (*NearbyResponse, error)
Nearby searches for active postcode units within a radius (default 300m) of a coordinate.
func (*Client) RateLimit ¶
func (c *Client) RateLimit() *RateLimitInfo
RateLimit returns the most recent rate limit quotas reported by the NIPOST gateway, or nil if no request has yet returned rate limit headers.
func (*Client) Reverse ¶
func (c *Client) Reverse(ctx context.Context, params ReverseParams) (*ReverseResponse, error)
Reverse resolves a geographic coordinate to the nearest active postcode unit.
type ClientOption ¶
type ClientOption func(*Client)
func WithAPIKey ¶
func WithAPIKey(key string) ClientOption
WithAPIKey sets the NIPOST API key sent in the X-API-Key header. An apiKey is optional for public endpoints (L1 lookup, search, assembly).
func WithBaseTransport ¶
func WithBaseTransport(rt http.RoundTripper) ClientOption
WithBaseTransport sets the underlying round tripper underneath the retry middleware.
func WithBaseURL ¶
func WithBaseURL(customURL string) ClientOption
WithBaseURL overrides the default gateway URL (e.g. for testing with httptest.Server).
func WithRateLimitRetry ¶
func WithRateLimitRetry(enabled bool, maxDelay time.Duration) ClientOption
WithRateLimitRetry configures automatic retry on 429 Too Many Requests responses. If enabled is false, 429 responses will not be retried. maxDelay sets the maximum duration the client is willing to sleep for a rate limit cooldown.
func WithRetryConfig ¶
func WithRetryConfig(cfg RetryConfig) ClientOption
WithRetryConfig configures backoff, jitter, and retry limits.
func WithTelemetry ¶
func WithTelemetry(t Telemetry) ClientOption
WithTelemetry registers custom observability hooks.
func WithTimeout ¶
func WithTimeout(d time.Duration) ClientOption
WithTimeout sets the overall client request timeout.
func WithTransport ¶
func WithTransport(rt http.RoundTripper) ClientOption
WithTransport explicitly overrides the entire round tripper stack (bypassing retries).
type LookupLevel ¶
type LookupLevel int
LookupLevel specifies the depth of attributes returned by a lookup request. Levels 1 is free; Levels 2-4 require commercial credits; Level 5 is restricted.
const ( LevelDefault LookupLevel = 0 // Default to level 1 Level1 LookupLevel = 1 // Free: Administrative boundary Level2 LookupLevel = 2 // Commercial: Street and locality names Level3 LookupLevel = 3 // Commercial: Building unit metadata Level4 LookupLevel = 4 // Commercial: Additional building use info Level5 LookupLevel = 5 // Restricted: High-precision point geometry )
type LookupResponse ¶
type LookupResponse struct {
Postcode string `json:"postcode"`
Valid bool `json:"valid"`
AdministrativeAddress *AdministrativeAddress `json:"administrative_address,omitempty"`
RecentHouseAddress *RecentHouseAddress `json:"recent_house_address,omitempty"`
BuildingUseStatus string `json:"building_use_status,omitempty"`
OtherBuildingInfo map[string]any `json:"other_building_info,omitempty"`
PointGeometry *PointGeometry `json:"point_geometry,omitempty"`
}
LookupResponse represents the graded attributes returned by GET /v1/lookup.
type MetricsRecorder ¶
type MetricsRecorder interface {
RecordDuration(ctx context.Context, method, endpoint string, statusCode int, duration time.Duration)
AddInflight(ctx context.Context, delta int64)
}
MetricsRecorder defines standard metrics contracts for client operations.
type NearbyParams ¶
type NearbyParams struct {
Latitude float64
Longitude float64
RadiusM float64 // Search radius in meters (default 300, max 300)
}
NearbyParams configures location search around a geographic coordinate.
type NearbyResponse ¶
type NearbyResponse struct {
Results []NearbyUnit `json:"results"`
}
NearbyResponse contains location units within the requested radius.
type NearbyUnit ¶
type NearbyUnit struct {
Postcode string `json:"postcode"`
Display string `json:"display"`
DistanceM float64 `json:"distance_m"`
Confidence string `json:"confidence"`
StateName string `json:"state_name,omitempty"`
LGAName string `json:"lga_name,omitempty"`
Address string `json:"address,omitempty"`
}
NearbyUnit represents a building unit found near a coordinate.
type PointGeometry ¶
type PointGeometry struct {
Type string `json:"type,omitempty"`
Coordinates []float64 `json:"coordinates,omitempty"` // [lng, lat]
}
PointGeometry represents GeoJSON point coordinates (L5).
type Postcode ¶
type Postcode struct {
// contains filtered or unexported fields
}
Postcode represents an immutable, validated 11-byte Nigerian postcode. Backed by a fixed byte array to ensure zero heap escapes.
func (Postcode) AppendText ¶
AppendText implements encoding.TextAppender for zero-alloc formatting. Outputs the spaced format: "AA 99 H77 BB 55".
func (Postcode) BuildingUnit ¶
func (Postcode) Formatted ¶
Formatted returns the canonical hyphenated representation (e.g. "EK-01-A03-FK-01").
func (Postcode) MarshalText ¶
func (*Postcode) UnmarshalText ¶
type RateLimitInfo ¶
type RateLimitInfo struct {
Limit int // Maximum requests allowed in current window (from X-RateLimit-Limit)
Remaining int // Remaining requests in current window (from X-RateLimit-Remaining)
ResetAt time.Time // Timestamp when quota resets (from X-RateLimit-Reset or Retry-After)
RetryAfter time.Duration // Cooldown duration requested by server (from Retry-After or X-RateLimit-Reset)
}
RateLimitInfo contains the rate-limiting quotas returned by the NIPOST API gateway as documented in https://docs.postcode.gov.ng/authentication.
func ParseRateLimitInfo ¶
func ParseRateLimitInfo(h http.Header) *RateLimitInfo
ParseRateLimitInfo extracts rate limit quotas and cooldown durations from HTTP response headers.
type RecentHouseAddress ¶
type RecentHouseAddress struct {
Address string `json:"address,omitempty"`
Recent string `json:"recent,omitempty"`
HouseNumber string `json:"house_number,omitempty"`
StreetName string `json:"street_name,omitempty"`
LocalityName string `json:"locality_name,omitempty"`
}
RecentHouseAddress contains residential and street metadata (L2+).
type RetryConfig ¶
type RetryConfig struct {
MaxRetries int // Maximum retry attempts for transient errors (default: 3)
BaseDelay time.Duration // Initial exponential backoff delay (default: 100ms)
MaxDelay time.Duration // Maximum exponential backoff delay (default: 2s)
DisableRateLimit bool // If true, 429 Too Many Requests will not be retried automatically
MaxRateLimitDelay time.Duration // Maximum sleep duration client will wait for a 429 cooldown (default: 10s)
}
RetryConfig configures backoff, jitter, and rate-limit handling for HTTP requests.
type RetryTransport ¶
type RetryTransport struct {
Base http.RoundTripper
Config RetryConfig
}
func NewRetryTransport ¶
func NewRetryTransport(base http.RoundTripper, cfg RetryConfig) *RetryTransport
type ReverseParams ¶
type ReverseParams struct {
Latitude float64
Longitude float64
MaxDistanceM float64 // Search radius in meters (default 25, max 250)
}
ReverseParams configures reverse geocoding to snap coordinates to the nearest unit.
type ReverseResponse ¶
type ReverseResponse struct {
Found bool `json:"found"`
Coordinate []float64 `json:"coordinate"` // [lng, lat]
Unit *NearbyUnit `json:"unit,omitempty"`
Area string `json:"area,omitempty"`
District string `json:"district,omitempty"`
State string `json:"state,omitempty"`
Message string `json:"message,omitempty"`
RadiusM float64 `json:"radius_m"`
}
ReverseResponse represents the result of reverse geocoding a coordinate.
type Segments ¶
type Segments struct {
State string `json:"state"`
LGA string `json:"lga"`
District string `json:"district"`
Area string `json:"area"`
Unit string `json:"unit"`
}
Segments represents the 5 administrative components of a Nigerian postcode.
type Span ¶
type Span interface {
End()
RecordError(err error)
SetAttribute(key, value string)
SetStatus(code int, msg string)
}
Span encapsulates active span operations without coupling to any trace vendor.
type Telemetry ¶
type Telemetry struct {
Tracer Tracer
Metrics MetricsRecorder
}
Telemetry bundles tracing and metrics hooks.
func NopTelemetry ¶
func NopTelemetry() Telemetry
NopTelemetry provides zero-overhead, no-op telemetry by default.