Skip to content
This repository was archived by the owner on Sep 2, 2024. It is now read-only.

Commit 86d58ef

Browse files
committed
added initial backend package doc and renamed NewDatabase to Collection
1 parent d797718 commit 86d58ef

File tree

6 files changed

+64
-17
lines changed

6 files changed

+64
-17
lines changed

backend/backend.go

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,42 @@
1+
// Package backend allows a Go program to import a standard Go package
2+
// instead of self-hosting the backend API.
3+
//
4+
// You need to call the Setup function to initialize all services passing
5+
// a config.AppConfig. You may create environment variables and load the config
6+
// directly from confing.LoadConfig.
7+
//
8+
// The building blocks of StaticBackend are exported as variable and can be
9+
// used directly accessing their interface's functions. For instance
10+
// to use the Volatilizer (cache and pub/sub) you'd use the Cache variable:
11+
//
12+
// if err := backend.Cache.Set("key", "value"); err != nil {
13+
// return err
14+
// }
15+
// val, err := backend.Cache.Get("key")
16+
//
17+
// The available services are as follow:
18+
// 1. Cache: caching and pub/sub
19+
// 2. DB: a raw Persister instance (see below for when to use it)
20+
// 3. Filestore: raw blob storage
21+
// 4. Emailer: to send emails
22+
// 5. Config: the config that was passed to Setup
23+
// 6. Log: logger
24+
//
25+
// You may see those services as raw building blocks to give you the most
26+
// flexibility. For easy of use, this package wraps important / commonly used
27+
// functionalities into more developer friendly implementation.
28+
//
29+
// For instance, the Membership function wants a model.DatabaseConfig and allow
30+
// the caller to create account and user as well as reseting password etc.
31+
//
32+
// To contrast, all of those can be done from your program by using the DB
33+
// (Persister) data store, but for convenience this package offers easier /
34+
// ready-made functions for common use-case.
35+
//
36+
// StaticBackend makes your Go web application multi-tenant by default.
37+
// For this reason you must supply a model.DatabaseConfig and sometimes a
38+
// model.auth (user performing the actions) to the different parts of the system
39+
// so the data and security are applied to the right tenant, account and user.
140
package backend
241

342
import (
@@ -150,7 +189,7 @@ func openMongoDatabase(dbHost string) (*mongodrv.Client, error) {
150189
}
151190

152191
if err := cl.Ping(ctx, readpref.Primary()); err != nil {
153-
return nil, fmt.Errorf("Ping failed: %v", err)
192+
return nil, fmt.Errorf("ping failed: %v", err)
154193
}
155194

156195
return cl, nil
@@ -170,20 +209,15 @@ func openPGDatabase(dbHost string) (*sql.DB, error) {
170209
return dbConn, nil
171210
}
172211

173-
// NewID generates a new unique identifier
174-
func NewID() string {
175-
return DB.NewID()
176-
}
177-
178-
func findAuth(token string) model.Auth {
212+
func findAuthz(token string) model.Auth {
179213
auth, err := middleware.ValidateAuthKey(DB, Cache, context.Background(), token)
180214
if err != nil {
181215
return model.Auth{}
182216
}
183217
return auth
184218
}
185219

186-
func findBase(baseID string) model.DatabaseConfig {
220+
func findBasez(baseID string) model.DatabaseConfig {
187221
var conf model.DatabaseConfig
188222
if err := Cache.GetTyped(baseID, &conf); err != nil {
189223
db, err := DB.FindDatabase(baseID)

backend/database.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@ import (
77
"github.com/staticbackendhq/core/model"
88
)
99

10-
// Database enables all CRUD and querying operations on a type
10+
// Database enables all CRUD and querying operations on a specific type
1111
type Database[T any] struct {
1212
auth model.Auth
1313
conf model.DatabaseConfig
1414
}
1515

16-
// NewDatabase returns a ready to use Database to perform operations on a type
17-
func NewDatabase[T any](token, baseID string) Database[T] {
16+
// Collection returns a ready to use Database to perform operations on a specific type
17+
func Collection[T any](auth model.Auth, base model.DatabaseConfig) Database[T] {
1818
return Database[T]{
19-
auth: findAuth(token),
20-
conf: findBase(baseID),
19+
auth: auth,
20+
conf: base,
2121
}
2222
}
2323

backend/database_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func newTask(title string, done bool) Task {
3232
}
3333

3434
func TestDatabaseCreate(t *testing.T) {
35-
db := backend.NewDatabase[Task](jwtToken, base.ID)
35+
db := backend.Collection[Task](adminAuth, base)
3636

3737
task := newTask("db create", false)
3838
task, err := db.Create("tasks", task)
@@ -51,7 +51,7 @@ func TestDatabaseCreate(t *testing.T) {
5151
}
5252

5353
func TestDatabaseList(t *testing.T) {
54-
db := backend.NewDatabase[Task](jwtToken, base.ID)
54+
db := backend.Collection[Task](adminAuth, base)
5555

5656
tasks := []Task{
5757
newTask("t1", false),
@@ -72,7 +72,7 @@ func TestDatabaseList(t *testing.T) {
7272
}
7373

7474
func TestDatabaseQuery(t *testing.T) {
75-
db := backend.NewDatabase[Task](jwtToken, base.ID)
75+
db := backend.Collection[Task](adminAuth, base)
7676

7777
tasks := []Task{
7878
newTask("qry1", false),

backend/file.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/staticbackendhq/core/model"
1111
)
1212

13+
// FileStore exposes file functions
1314
type FileStore struct {
1415
auth model.Auth
1516
conf model.DatabaseConfig
@@ -22,11 +23,14 @@ func newFile(auth model.Auth, conf model.DatabaseConfig) FileStore {
2223
}
2324
}
2425

26+
// SavedFile when a file is saved it has an ID and an URL
2527
type SavedFile struct {
2628
ID string `json:"id"`
2729
URL string `json:"url"`
2830
}
2931

32+
// Save saves a file content to the file storage (Storer interface) and to the
33+
// database
3034
func (f FileStore) Save(filename, name string, file io.ReadSeeker, size int64) (sf SavedFile, err error) {
3135
ext := filepath.Ext(name)
3236

@@ -67,6 +71,7 @@ func (f FileStore) Save(filename, name string, file io.ReadSeeker, size int64) (
6771
return
6872
}
6973

74+
// Delete removes a file from storage and database
7075
func (f FileStore) Delete(fileID string) error {
7176
file, err := DB.GetFileByID(f.conf.Name, fileID)
7277
if err != nil {

backend/user.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ func (u User) Register(email, password string) (string, error) {
9999
return token, nil
100100
}
101101

102+
// CreateAccountAndUser creates an account with a user
102103
func (u User) CreateAccountAndUser(email, password string, role int) ([]byte, model.User, error) {
103104
acctID, err := DB.CreateAccount(u.conf.Name, email)
104105
if err != nil {
@@ -112,6 +113,7 @@ func (u User) CreateAccountAndUser(email, password string, role int) ([]byte, mo
112113
return jwtBytes, tok, nil
113114
}
114115

116+
// CreateUser creates a user for an Account
115117
func (u User) CreateUser(accountID, email, password string, role int) ([]byte, model.User, error) {
116118
b, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
117119
if err != nil {
@@ -209,6 +211,7 @@ func (u User) UserSetPassword(email, oldpw, newpw string) error {
209211
return DB.UserSetPassword(u.conf.Name, tok.ID, string(b))
210212
}
211213

214+
// GetAuthToken returns a session token for a user
212215
func (u User) GetAuthToken(tok model.User) (jwtBytes []byte, err error) {
213216
token := fmt.Sprintf("%s|%s", tok.ID, tok.Token)
214217

@@ -238,6 +241,7 @@ func (u User) GetAuthToken(tok model.User) (jwtBytes []byte, err error) {
238241
return
239242
}
240243

244+
// GetJWT returns a session token from a token
241245
func GetJWT(token string) ([]byte, error) {
242246
now := time.Now()
243247
pl := model.JWTPayload{
@@ -255,6 +259,7 @@ func GetJWT(token string) ([]byte, error) {
255259

256260
}
257261

262+
// MagicLinkData magic links for no-password sign-in
258263
type MagicLinkData struct {
259264
FromEmail string `json:"fromEmail"`
260265
FromName string `json:"fromName"`
@@ -264,6 +269,7 @@ type MagicLinkData struct {
264269
MagicLink string `json:"link"`
265270
}
266271

272+
// SetupMagicLink initialize a magic link and send the email to the user
267273
func (u User) SetupMagicLink(data MagicLinkData) error {
268274
data.Email = strings.ToLower(data.Email)
269275

@@ -292,6 +298,8 @@ func (u User) SetupMagicLink(data MagicLinkData) error {
292298
return nil
293299
}
294300

301+
// ValidateMagicLink validates a magic link code and returns a session token on
302+
// success
295303
func (u User) ValidateMagicLink(email, code string) (string, error) {
296304
email = strings.ToLower(email)
297305

db.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ func (database *Database) del(w http.ResponseWriter, r *http.Request) {
324324
}
325325

326326
func (database *Database) newID(w http.ResponseWriter, r *http.Request) {
327-
id := backend.NewID()
327+
id := backend.DB.NewID()
328328
respond(w, http.StatusOK, id)
329329
}
330330

0 commit comments

Comments
 (0)