api

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Mar 3, 2026 License: MIT Imports: 2 Imported by: 0

README

shared/api

Wire-format DTOs shared between the backend API and frontend apiclient.

Rules

1. Create an api type when both sides encode/decode it

If the backend marshals a response and the frontend (or any other client) unmarshals it, define a named type here. No inline anonymous structs, no map[string]T literals on either side.

// Good
writeJSON(w, api.LastModifiedResponse{LastModifiedAt: lastModified})

var result api.LastModifiedResponse
utils.Decode(resp.Body, &result)

// Bad — fields can drift silently
writeJSON(w, map[string]time.Time{"last_modified_at": lastModified})

var result struct { LastModifiedAt time.Time `json:"last_modified_at"` }
2. Don't wrap domain types — decode them directly

If the response is a domain type (or a slice of one), serialize/deserialize it directly. An api type that only wraps a domain type adds indirection with no benefit.

// Good — domain type used directly on the wire
writeJSON(w, []domain.Message{...})

var messages []domain.Message
utils.Decode(resp.Body, &messages)

// Bad — pointless wrapper
type UserActivityResponse struct { Messages []domain.Message }

Trade-off: this couples the wire format to the domain model. If a domain type gains a sensitive internal field with JSON tags, it will be exposed. Add an api type if you need to diverge.

3. No response body when status is enough

Mutations that convey no information beyond success (e.g. delete, logout, revoke) return only an HTTP status code. No {"message": "done"} bodies.

// Good
w.WriteHeader(http.StatusOK)

// Bad
writeJSON(w, map[string]string{"message": "User blacklisted successfully"})

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BlacklistResponse

type BlacklistResponse struct {
	Users []domain.BlacklistEntry `json:"users"`
	Page  int                     `json:"page"`
}

type BlacklistUserRequest

type BlacklistUserRequest struct {
	Reason string `json:"reason"`
}

type CheckConfirmationCodeRequest

type CheckConfirmationCodeRequest struct {
	Email            string `json:"email" validate:"required,email"`
	ConfirmationCode string `json:"confirmation_code" validate:"required"`
	RefSource        string `json:"ref_source"`
}

type CreateBoardRequest

type CreateBoardRequest struct {
	Name          string         `json:"name" validate:"required"`
	ShortName     string         `json:"short_name" validate:"required"`
	AllowedEmails *domain.Emails `json:"allowed_emails,omitempty"`
}

type CreateMessageRequest

type CreateMessageRequest struct {
	Text            string              `json:"text,omitempty"`
	ShowEmailDomain bool                `json:"show_email_domain,omitempty"`
	Attachments     *domain.Attachments `json:"attachments,omitempty"`
	ReplyTo         *domain.Replies     `json:"reply_to,omitempty"`
}

type CreateMessageResponse

type CreateMessageResponse struct {
	Id   int64 `json:"id"`
	Page int   `json:"page"` // Page number where the message appears
}

CreateMessageResponse returns the ID of the created message and its page

type CreateThreadRequest

type CreateThreadRequest struct {
	Title     string               `json:"title" validate:"required"`
	IsPinned  bool                 `json:"is_pinned,omitempty"`
	OpMessage CreateMessageRequest `json:"op_message"`
}

type CreateThreadResponse added in v0.1.4

type CreateThreadResponse struct {
	ID int64 `json:"id"`
}

type GenerateInviteResponse added in v0.1.4

type GenerateInviteResponse struct {
	InviteCode string    `json:"invite_code"`
	ExpiresAt  time.Time `json:"expires_at"`
}

type InviteListResponse added in v0.1.1

type InviteListResponse struct {
	Invites []domain.InviteCode `json:"invites"`
	Page    int                 `json:"page"`
}

type LastModifiedResponse added in v0.1.4

type LastModifiedResponse struct {
	LastModifiedAt time.Time `json:"last_modified_at"`
}

type LoginRequest

type LoginRequest struct {
	Email    string `json:"email" validate:"required,email"`
	Password string `json:"password" validate:"required"`
}

type LoginResponse

type LoginResponse struct {
	Message     string `json:"message"`
	AccessToken string `json:"access_token,omitempty"` // Token for non-cookie clients (mobile, API clients)
}

type RecordReferralVisitRequest added in v0.1.3

type RecordReferralVisitRequest struct {
	Source string `json:"source" validate:"required"`
}

type RegisterRequest

type RegisterRequest struct {
	Email    string `json:"email" validate:"required,email"`
	Password string `json:"password" validate:"required"`
}

type RegisterWithInviteRequest added in v0.1.3

type RegisterWithInviteRequest struct {
	InviteCode string `json:"invite_code" validate:"required"`
	Password   string `json:"password" validate:"required"`
	RefSource  string `json:"ref_source"`
}

type RegisterWithInviteResponse added in v0.1.4

type RegisterWithInviteResponse struct {
	Message string `json:"message"`
	Email   string `json:"email"`
}

type TogglePinnedThreadResponse added in v0.1.4

type TogglePinnedThreadResponse struct {
	IsPinned bool `json:"is_pinned"`
}

Jump to

Keyboard shortcuts

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