Categorygithub.com/ainsleyclark/go-payloadcms
modulepackage
0.0.5
Repository: https://github.com/ainsleyclark/go-payloadcms.git
Documentation: pkg.go.dev

# README

Go Payload CMS

GoLang client library & SDK for Payload CMS

Go Report Card Maintainability GoDoc Test Lint
codecov ainsley.dev Twitter Handle

Introduction

Go Payload is a GoLang client library for Payload CMS. It provides a simple and easy-to-use interface for interacting with the Payload CMS API by saving you the hassle of dealing with unmarshalling JSON responses into your Payload collections and globals.

Installation

go get -u github.com/ainsleyclark/go-payloadcms

Quick Start

import (
	"github.com/ainsleyclark/go-payloadcms"
)

type Entity struct {
	ID    int    `json:"id"`
	Email string `json:"email"`
	Name  string `json:"name"`
	// ... other fields
}

func main() {
	client, err := payloadcms.New(
		payloadcms.WithBaseURL("http://localhost:8080"),
		payloadcms.WithAPIKey("api-key"),
	)
	
	if err != nil {
		log.Fatalln(err)
	}
	
	var entities payloadcms.ListResponse[Entity]
	resp, err := client.Collections.List(context.Background(), "users", payloadcms.ListParams{}, &entities)
	if err != nil {
		log.Fatalln(err)
	}
	
	fmt.Printf("Received status: %d, with body: %s\n", resp.StatusCode, string(resp.Content))
}

Docs

Documentation can be found at the Go Docs, but we have included a kick-start guide below to get you started.

Services

The client provides the services as defined below. Each

  • Collections
  • Globals
  • Media

Collections

The collections service provides methods to interact with the collections in Payload CMS. For more information please visit the docs here.

FindByID

var entity Entity // Any struct that conforms to your collection schema.
resp, err := client.Collections.FindByID(context.Background(), "collection", 1, &entity)
if err != nil {
	fmt.Println(err)
	return
}

List

var entities payloadcms.ListResponse[Entity] // Must use ListResponse with generic type.
resp, err := client.Collections.List(context.Background(), "collection", payloadcms.ListParams{
	Sort:  "-createdAt",
	Limit: 10,
	Page:  1,
}, entities)
if err != nil {
	fmt.Println(err)
	return
}

Create

var entity Entity // Any struct representing the entity to be created.
resp, err := client.Collections.Create(context.Background(), "collection", entity)
if err != nil {
	fmt.Println(err)
	return
}
fmt.Println(string(resp.Content)) // Can unmarshal into response struct if needed.

UpdateByID

var entity Entity // Any struct representing the updated entity.
resp, err := client.Collections.UpdateByID(context.Background(), "collection", 1, entity)
if err != nil {
	fmt.Println(err)
	return
}
fmt.Println(string(resp.Content)) // Can unmarshal into response struct if needed.

DeleteByID

resp, err := client.Collections.DeleteByID(context.Background(), "collection", 1)
if err != nil {
	fmt.Println(err)	
	return
}
// Use response data as needed

Globals

The globals service provides methods to interact with the globals in Payload CMS. For more information please visit the docs here.

Get

var global Global // Any struct representing a global type.
resp, err := client.Globals.Get(context.Background(), "global", &global)
if err != nil {
	fmt.Println(err)
	return
}

Update

var global Global // Any struct representing a global type.
resp, err := client.Globals.Update(context.Background(), "global", global)
if err != nil {
	fmt.Println(err)
	return
}
fmt.Println(string(resp.Content)) // Can unmarshal into response struct if needed.

Media

The media service provides methods to upload media types to Payload CMS. For more information please visit the docs here.

Upload

file, err := os.Open("path/to/file")
if err != nil {
	fmt.Println(err)
	return
}

media := &payloadcms.CreateResponse[Media]{}
_, err = m.payload.Media.UploadFromURL(ctx, file, Media{Alt: "alt"}, &media, payloadcms.MediaOptions{
	Collection:       "media",
})

if err != nil {
	fmt.Println(err)
	return
}

UploadFromURL

media := &payloadcms.CreateResponse[Media]{}
_, err = m.payload.Media.UploadFromURL(ctx, "https://payloadcms.com/picture-of-cat.jpg", Media{Alt: "alt"}, &media, payloadcms.MediaOptions{
	Collection:       "media",
})

if err != nil {
	fmt.Println(err)
	return
}

Queries

The Params allows you to add filters, sort order, pagination, and other query parameters. Here's an example:

import (
	"context"
	"fmt"
	"github.com/ainsleyclark/go-payloadcms"
)

func main() {
	client, err := payloadcms.New(
		payloadcms.WithBaseURL("http://localhost:8080"),
		payloadcms.WithAPIKey("api-key"),
	)
	if err != nil {
		log.Fatalln(err)
	}

	var entities payloadcms.ListResponse[Entity]
	
	params := payloadcms.ListParams{
		Sort: "-createdAt",          
		Limit: 10,                  
		Page: 1,                     
		Where: payloadcms.Query().Equals("status", "active").GreaterThan("age", "18"),
	}

	resp, err := client.Collections.List(context.Background(), "users", params, &entities)
	if err != nil {
		log.Fatalln(err)
	}

	fmt.Printf("Received status: %d, with body: %s\n", resp.StatusCode, string(resp.Content))
}

Mocks

Mock implementations can be found in payloadfakes package located in fakes directory.

They provide mock implementations of all the services provided by the client for convenience.

Example:

func TestPayload(t *testing.T) {
	// Create a new mock collection service
	mockCollectionService := payloadfakes.NewMockCollectionService()
	
	// Define the behavior of the FindByID method
	mockCollectionService.FindByIDFunc = func (ctx context.Context,
		collection payloadcms.Collection,
		id int,
		out any,
	) (payloadcms.Response, error) {
		// Custom logic for the mock implementation
		return payloadcms.Response{}, nil
	}
	
	// Use the mock collection service in your tests
	myFunctionUsingCollectionService(mockCollectionService)
}

Response and Error Types

The library defines custom response and error types to provide a more convenient way to interact with the API.

  • Response: This struct wraps the standard http.Response returned by the API and provides additional fields for easier access to response data and potential errors.
    • Content: The response body bytes.
    • Message: A user-friendly message extracted from the response (if available).
    • Errors: A list of Error structs containing details about any API errors encountered.
  • Error: This struct represents a single API error with a Message field containing the error description.

These types are used throughout the library to handle successful responses and API errors consistently.

Development

Setup

To get set up with Go Payload simply clone the repo and run the following:

make setup

This will install all dependencies and set up the project for development.

Payload Dev Env

Within the ./dev directory, you will find a local instance of Payload CMS that can be used for testing the client. To get setup with Payload, simply follow the steps below.

Copy the environment file and replace where necessary. The postgres-db adapater is currently being used for the database.

cp .env.example .env

Then run the Payload instance like you would any other installation.

pnpm run dev

TODOs

Contributing

Contributions are welcome! If you find any bugs or have suggestions for improvement, please open an issue or submit a pull request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Trademark

ainsley.dev and the ainsley.dev logo are either registered trademarks or trademarks of ainsley.dev LTD in the United Kingdom and/or other countries. All other trademarks are the property of their respective owners.

# Packages

Package payloadfakes provides mock implementations of various Payload CMS services.

# Functions

New creates a new Payload CMS client.
Query creates a new instance of QueryBuilder.
WithAPIKey is a functional option to set the API key for the Payload API.
WithBaseURL is a functional option to set the base URL of the Payload API.
WithClient is a functional option to set the HTTP client of the Payload API.

# Constants

AllItems is a constant that can be used to retrieve all items from a collection.
CollectionUsers defines the Payload users collection slug.

# Structs

Client represents a Payload CMS client.
CollectionServiceOp handles communication with the collection related methods of the Payload API.
No description provided by the author
Error defines a singular API error.
GlobalsServiceOp handles communication with the global related methods of the Payload API.
ListParams represents additional query parameters for the find endpoint.
No description provided by the author
MediaOptions represents non-required options for uploading media.
MediaServiceOp represents a service for managing media within Payload.
QueryBuilder represents the type for building Payload CMS where queries for Find/List routes.
Response is a PayloadAPI API response.
No description provided by the author

# Interfaces

CollectionService is an interface for interacting with the collection endpoints of the Payload API.
GlobalsService is an interface for interacting with the global endpoints of the Payload API.
MediaService is an interface for uploading media to the Payload API.
Service is an interface that defines common methods for interacting with the Payload API.

# Type aliases

Collection represents a collection slug from Payload.
Errors defines a list of Payload API errors.
Global represents a global slug from Payload.
Option is a functional option type that allows us to configure the Client.