GoAT Site implements Standard.site in Go.
Use anhgelus.world/xrpc, a lightweight XRPC client.
Main repository is hosted on Tangled, an ATProto forge.
Note
Check anhgelus.world/xrpc's documentation first!
Get the module with:
go get -u tangled.org/anhgelus.world/goat-siteEach Standard.site lexicon is implemented:
Publicationis forsite.standard.publication;Documentis forsite.standard.document;Subscriptionis forsite.standard.graph.subscription.
These types implement xrpc.Record, an interface describing records.
You can get, list, create, update or delete them with functions:
xrpc.GetRecord[*site.Publication]to get a publication;xrpc.ListRecords[*site.Document]to list documents;xrpc.CreateRecordto create a new document;xrpc.PutRecordto update a subscription;xrpc.DeleteRecord[*site.Publication]to delete a publication.
You can verify a publication with Publication.Verify and a document with
Document.Verify:
var pub *site.Publication
var did *atproto.DID
var client xrpc.Client
var rkey atproto.RecordKey
valid, err := pub.Verify(context.TODO(), client, did, rkey)
if err != nil {
panic(err)
}
if !valid {
println("invalid publication :(")
}
var doc *site.Document
pubUrl, err := doc.PublicationURL(context.TODO(), client)
if err != nil {
panic(err)
}
valid, err = doc.Verify(context.TODO(), client, pubUrl, did, rkey)
if err != nil {
panic(err)
}
if !valid {
panic("invalid document :(")
}Document.Content is an open union: you can create your own lexicon to use it.
If the NSID of your lexicon is tld.example.content and its definition in Go is:
type Content struct {
// Pars represents the paragraphs in [Content].
Pars []string `json:"pars"`
}To use it, you have to implement site.Record:
var CollectionContent = atproto.NewNSIDBuilder(`tld.example`).Name("content").Build()
func (c *Content) Collection() *atproto.NSID {
return CollectionContent
}But if you use xrpc.GetRecord[*site.Document] to retrieve one, it will return a simple site.Document without your
custom content!
The Document.Content field is a xrpc.Union, a type representing an open union.
You can get the collection of the content with Union.Collection() and the raw bytes with Union.Raw.
You can also directly parse your Content with Union.As:
var doc *site.Document
c := new(Content)
// returns an error if it cannot parse or if the type is invalid
if !doc.Content.As(c) {
panic("not a Content :(")
}See anhgelus.world/xrpc documentation.
Lexicons defined by Standard.site can be extended.
To extend a lexicon, you can create a new type and embed the base lexicon:
type CustomPublication struct {
site.Publication
// your custom fields
}You can call any functions with this new lexicon: the embedded base lexicon already implements the xrpc.Record
interface!