Documentation
¶
Overview ¶
Package shipreal is the official Go client for the public ShipReal course API: search the curriculum, read a module, read current pricing.
There is no authentication. No key, no account, no OAuth, no signup: every endpoint is a public read served from the edge, so a client that asks you for a credential for this domain is not this one.
There is also no write path. Buying runs through a hosted checkout that a human completes, which is why nothing here creates an order. When someone decides to buy, hand them the checkout link.
Standard library only, on purpose: installing this cannot drag a transitive dependency tree into an agent's environment.
c := shipreal.New()
page, err := c.Search(ctx, shipreal.SearchParams{Query: "caching"})
Index ¶
- Constants
- type AskEvent
- type AskMeta
- type AskResponse
- type AskResult
- type BatchItem
- type BatchRequest
- type BatchResponse
- type Client
- func (c *Client) Ask(ctx context.Context, query string) (*AskResponse, error)
- func (c *Client) AskStream(ctx context.Context, query string, fn func(AskEvent) error) error
- func (c *Client) Batch(ctx context.Context, requests []BatchRequest) (*BatchResponse, error)
- func (c *Client) Course(ctx context.Context) (*Course, error)
- func (c *Client) Module(ctx context.Context, slugOrTitle string) (*Module, error)
- func (c *Client) Modules(ctx context.Context, query string) ([]Module, error)
- func (c *Client) Pricing(ctx context.Context) (*Pricing, error)
- func (c *Client) Search(ctx context.Context, params SearchParams) (*Page, error)
- type Course
- type Error
- type FreePlan
- type Links
- type Module
- type Option
- type Page
- type Pagination
- type Plan
- type Pricing
- type RegionPrice
- type SearchParams
Constants ¶
const ( // DefaultBaseURL is the production origin. DefaultBaseURL = "https://shipreal.dev" // APIVersion is the path segment this client speaks. Breaking changes // ship as a new segment beside it rather than as a change underneath; // every response carries a Deprecation header, false today. APIVersion = "v1" // Version of this client, sent in the User-Agent. Version = "1.0.1" // MaxBatch is the server's ceiling on requests in one batch call. MaxBatch = 20 )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AskEvent ¶
type AskEvent struct {
Event string `json:"-"`
Meta AskMeta `json:"_meta"`
Results []AskResult `json:"results"`
}
AskEvent is one server-sent event from AskStream: "start", then one "result" per hit, then "complete".
type AskMeta ¶
type AskMeta struct {
ResponseType string `json:"response_type"`
Version string `json:"version"`
Query string `json:"query"`
Site string `json:"site"`
Count int `json:"count"`
}
AskMeta is the NLWeb _meta block naming the response type and version.
type AskResponse ¶
AskResponse is the NLWeb shape: a question in, structured results out.
type AskResult ¶
type AskResult struct {
Type string `json:"@type"`
Name string `json:"name"`
URL string `json:"url"`
Description string `json:"description"`
Score float64 `json:"score"`
Site string `json:"site"`
SchemaObject json.RawMessage `json:"schema_object"`
}
AskResult is one natural-language hit, with its schema.org object attached.
type BatchItem ¶
type BatchItem struct {
ID string `json:"id"`
Status int `json:"status"`
Body json.RawMessage `json:"body"`
}
BatchItem is one result inside a batch response. Each carries its own status, so check per item rather than assuming the whole batch succeeded.
type BatchRequest ¶
type BatchRequest struct {
ID string `json:"id,omitempty"`
Method string `json:"method,omitempty"`
Path string `json:"path"`
}
BatchRequest is one read inside a batch. Method is always GET; the API is read-only and a batch item that is not a read comes back 405.
type BatchResponse ¶
BatchResponse is the envelope. It answers 200 whenever it is itself valid, which is why the per-item statuses matter.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client talks to the ShipReal API. The zero value is not usable; call New.
func (*Client) Ask ¶
Ask puts a natural-language question to the NLWeb endpoint.
There is no model behind it: it runs the same keyword search as the REST API, which means it says so when nothing matches instead of inventing a module.
func (*Client) AskStream ¶
AskStream is the same question, streamed. It calls fn for each server-sent event as it arrives and stops early if fn returns an error, which it returns unchanged.
func (*Client) Batch ¶
func (c *Client) Batch(ctx context.Context, requests []BatchRequest) (*BatchResponse, error)
Batch runs several reads in one round trip, up to MaxBatch.
func (*Client) Modules ¶
Modules returns every matching module, following pagination for you. An empty query returns the whole curriculum in course order.
type Course ¶
type Course struct {
Name string `json:"name"`
Title string `json:"title"`
Description string `json:"description"`
Parts int `json:"parts"`
Modules int `json:"modules"`
Chapters int `json:"chapters"`
Language string `json:"language"`
Subtitles []string `json:"subtitles"`
URL string `json:"url"`
}
Course is the summary: totals, language and subtitle languages.
type Error ¶
type Error struct {
Status int `json:"status"`
Type string `json:"type"`
Title string `json:"title"`
Detail string `json:"detail"`
// URL that produced the error.
URL string `json:"-"`
}
Error is any non-2xx response, carrying the RFC 9457 problem details the server sent.
Branch on Type rather than Status: the status says a request failed, the type says which failure it was, and only the second is stable enough to switch on.
type FreePlan ¶
type FreePlan struct {
Price int `json:"price"`
Currency string `json:"currency"`
Includes string `json:"includes"`
URL string `json:"url"`
}
FreePlan is the permanent free tier. Not a trial: no account and no expiry.
type Links ¶
type Links struct {
Self string `json:"self"`
First string `json:"first"`
Last string `json:"last"`
Next *string `json:"next"`
Prev *string `json:"prev"`
}
Links are absolute URLs for walking the pages.
type Module ¶
type Module struct {
Slug string `json:"slug"`
Title string `json:"title"`
Part string `json:"part"`
Description string `json:"description"`
Chapters int `json:"chapters"`
Minutes int `json:"minutes"`
// URL of the free video overview.
URL string `json:"url"`
}
Module is one module of the curriculum.
type Option ¶
type Option func(*Client)
Option configures a Client.
func WithBaseURL ¶
WithBaseURL points the client at a different origin, e.g. a local worker.
func WithHTTPClient ¶
WithHTTPClient supplies your own http.Client, for a custom transport or timeout.
func WithSandbox ¶
WithSandbox routes reads at the frozen fixture data: the same code path and the same shapes over contents that never change, so a test written against it stays green when the curriculum moves. Fixture prices are 1 unit and fixture links point at example.invalid, so sandbox data that leaks into real output is obvious. See https://shipreal.dev/sandbox.
type Page ¶
type Page struct {
Query *string `json:"query"`
Data []Module `json:"data"`
Pagination Pagination `json:"pagination"`
Links Links `json:"links"`
}
Page is one page of module results.
type Pagination ¶
type Pagination struct {
Page int `json:"page"`
Limit int `json:"limit"`
Total int `json:"total"`
Pages int `json:"pages"`
HasMore bool `json:"hasMore"`
// NextCursor is opaque and carries its own page size. Prefer it to
// incrementing Page: page numbers shift under a caller when the
// catalogue changes between calls, a cursor does not.
NextCursor *string `json:"nextCursor"`
}
Pagination describes the window a Page covers.
type Plan ¶
type Plan struct {
Intl RegionPrice `json:"intl"`
IL RegionPrice `json:"il"`
URL string `json:"url,omitempty"`
// MinSeats and PerSeat are only meaningful on the teams plan.
MinSeats int `json:"minSeats,omitempty"`
PerSeat bool `json:"perSeat,omitempty"`
}
Plan is a paid plan in both live billing regions.
type Pricing ¶
type Pricing struct {
Free FreePlan `json:"free"`
Complete Plan `json:"complete"`
Teams Plan `json:"teams"`
}
Pricing is every plan in every region. Two regional prices are live at once, so quoting one without naming its region is misleading: use Region to pick one deliberately.
type RegionPrice ¶
RegionPrice is one region's current and pre-discount price, as the display strings they are quoted in, symbol included.
type SearchParams ¶
type SearchParams struct {
Query string
Page int
Limit int
// Cursor overrides Page and Limit when set, because it carries the page
// size it was minted with.
Cursor string
}
SearchParams are the query, the window, and the cursor. All optional: an empty Query returns every module in course order.