datastore

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Feb 4, 2021 License: MIT Imports: 10 Imported by: 0

README

REST Layer Google Datastore Backend

godoc license build

This REST Layer resource storage backend stores data in a Google Datastore using datastore.

This backend used cmorent/rest-layer-datastore as a base and borrows structure and approach from rs/rest-layer-mongo. It uses the general library rather than specific appengine library.

Usage

import "github.com/ajcrowe/rest-layer-datastore"

Or use gopkg.in for a more stable v1 release

import "gopkg.in/ajcrowe/rest-layer-datastore.v1"

Create a datastore client

ctx := context.Background()
client, err := datastore.NewClient(ctx, "project-id")
if err != nil {
	log.Fatalf("Error connecting to Datastore: %s", err)
}

Then use this to create a new Handler for your resource binds

// params for the handler
namespace := "default"
entity := "users"
// bind the users resource with the datastore handler
index.Bind("users", user, datastore.NewHandler(client, namespace, entity), resource.DefaultConf)

You can also set a number of Datastore properties which you would like to exclude from being indexed with SetNoIndexProperties on your handler struct.

// create a handler for the resource.
index.Bind("users", user, datastore.NewHandler(client, namespace, entity).SetNoIndexProperties([]string{"prop1", "prop2"}), resource.DefaultConf)

Supported filter operators

  • $and
  • $or
  • $lt
  • $lte
  • $gt
  • $gte
  • $in
  • $nin
  • $exists

Documentation

Overview

Example
package main

import (
	"log"
	"net/http"

	gds "cloud.google.com/go/datastore"
	"github.com/ajcrowe/rest-layer-datastore"
	"github.com/rs/cors"
	"github.com/rs/rest-layer/resource"
	"github.com/rs/rest-layer/rest"
	"github.com/rs/rest-layer/schema"
	"google.golang.org/appengine/aetest"
)

var (
	user = schema.Schema{
		Fields: schema.Fields{
			"id":      schema.IDField,
			"created": schema.CreatedField,
			"updated": schema.UpdatedField,
			"name": {
				Required:   true,
				Filterable: true,
				Sortable:   true,
				Validator: &schema.String{
					MaxLen: 150,
				},
			},
		},
	}

	// Define a post resource schema
	post = schema.Schema{
		Fields: schema.Fields{
			"id":      schema.IDField,
			"created": schema.CreatedField,
			"updated": schema.UpdatedField,
			"user": {
				Required:   true,
				Filterable: true,
				Validator: &schema.Reference{
					Path: "users",
				},
			},
			"public": {
				Filterable: true,
				Validator:  &schema.Bool{},
			},
			"meta": {
				Schema: &schema.Schema{
					Fields: schema.Fields{
						"title": {
							Required: true,
							Validator: &schema.String{
								MaxLen: 150,
							},
						},
						"body": {
							Validator: &schema.String{
								MaxLen: 100000,
							},
						},
					},
				},
			},
		},
	}
)

func main() {
	ctx, done, err := aetest.NewContext()
	if err != nil {
		log.Fatal(err)
	}
	defer done()

	client, _ := gds.NewClient(ctx, "test-project")

	index := resource.NewIndex()

	users := index.Bind("users", user, datastore.NewHandler(client, "default", "users"), resource.Conf{
		AllowedModes: resource.ReadWrite,
	})

	users.Bind("posts", "user", post, datastore.NewHandler(client, "default", "posts"), resource.Conf{
		AllowedModes: resource.ReadWrite,
	})

	api, err := rest.NewHandler(index)
	if err != nil {
		log.Fatalf("Invalid API configuration: %s", err)
	}

	http.Handle("/", cors.New(cors.Options{OptionsPassthrough: true}).Handler(api))

	log.Print("Serving API on http://localhost:8080")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}
}
Output:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewClient

func NewClient(ctx context.Context, projectID string, opts ...option.ClientOption) (*datastore.Client, error)

Wrap datastore.NewClient to avoid user having to import this

Types

type Entity

type Entity struct {
	ID           string
	ETag         string
	Updated      time.Time
	Payload      map[string]interface{}
	NoIndexProps map[string]bool
}

Entity Is a representation of a Google Datastore entity

func (*Entity) Load

func (e *Entity) Load(ps []datastore.Property) error

Load implements the PropertyLoadSaver interface to process our dynamic payload data see https://godoc.org/cloud.google.com/go/datastore#hdr-The_PropertyLoadSaver_Interface

func (*Entity) Save

func (e *Entity) Save() ([]datastore.Property, error)

Save implements the PropertyLoadSaver interface to process our dynamic payload data see https://godoc.org/cloud.google.com/go/datastore#hdr-The_PropertyLoadSaver_Interface

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler handles resource storage in Google Datastore.

func NewHandler

func NewHandler(client *datastore.Client, namespace, entity string) *Handler

NewHandler creates a new Google Datastore handler

func (*Handler) Clear

func (d *Handler) Clear(ctx context.Context, q *query.Query) (int, error)

Clear clears all entities matching the lookup from the Datastore

func (*Handler) Delete

func (d *Handler) Delete(ctx context.Context, item *resource.Item) error

Delete deletes an item from the datastore

func (*Handler) Find

func (d *Handler) Find(ctx context.Context, q *query.Query) (*resource.ItemList, error)

Find entities matching the provided lookup from the Datastore

func (*Handler) Insert

func (d *Handler) Insert(ctx context.Context, items []*resource.Item) error

Insert inserts new entities

func (*Handler) SetNoIndexProperties

func (d *Handler) SetNoIndexProperties(props []string) *Handler

SetNoIndexProperties sets the handlers properties which should have noindex set.

func (*Handler) Update

func (d *Handler) Update(ctx context.Context, item *resource.Item, original *resource.Item) error

Update replace an entity by a new one in the Datastore

Jump to

Keyboard shortcuts

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