Documentation ¶
Overview ¶
Package service contains the gRPC Shopping Cart microservice implementation.
Index ¶
- Variables
- type CartService
- func (cs *CartService) AbandonShoppingCart(ctx context.Context, req *pbcart.AbandonShoppingCartRequest) (*pbcart.AbandonShoppingCartResponse, error)
- func (cs *CartService) AddItemToShoppingCart(ctx context.Context, req *pbcart.AddItemToShoppingCartRequest) (*pbcart.AddItemToShoppingCartResponse, error)
- func (cs *CartService) CheckoutShoppingCart(ctx context.Context, req *pbcart.CheckoutShoppingCartRequest) (*pbcart.CheckoutShoppingCartResponse, error)
- func (cs *CartService) CreateShoppingCart(ctx context.Context, req *pbcart.CreateShoppingCartRequest) (*pbcart.CreateShoppingCartResponse, error)
- func (cs *CartService) GetShoppingCartByID(ctx context.Context, req *pbcart.GetShoppingCartByIDRequest) (*pbcart.GetShoppingCartByIDResponse, error)
- func (cs *CartService) RemoveItemFromShoppingCart(ctx context.Context, req *pbcart.RemoveItemFromShoppingCartRequest) (*pbcart.RemoveItemFromShoppingCartResponse, error)
- func (cs *CartService) SetDeliveryAddress(ctx context.Context, req *pbcart.SetDeliveryAddressRequest) (*pbcart.SetDeliveryAddressResponse, error)
- type DocIteratorProxy
- type DocRefProxy
- func (p *DocRefProxy) Create(doc *firestore.DocumentRef, ctx context.Context, data interface{}) (*firestore.WriteResult, error)
- func (p *DocRefProxy) Delete(doc *firestore.DocumentRef, ctx context.Context) (*firestore.WriteResult, error)
- func (p *DocRefProxy) Get(doc *firestore.DocumentRef, ctx context.Context) (*firestore.DocumentSnapshot, error)
- func (p *DocRefProxy) Set(doc *firestore.DocumentRef, ctx context.Context, data interface{}) (*firestore.WriteResult, error)
- func (p *DocRefProxy) TransactionalCreate(doc *firestore.DocumentRef, tx *firestore.Transaction, data interface{}) error
- func (p *DocRefProxy) Update(doc *firestore.DocumentRef, ctx context.Context, updates []firestore.Update) (*firestore.WriteResult, error)
- type DocSnapProxy
- type DocumentIteratorProxy
- type DocumentRefProxy
- type DocumentSnapshotProxy
- type ItemCollGetterProxy
- type ItemCollectionGetterProxy
- type ItemsCollProxy
- type ItemsCollectionProxy
- type QueryExecProxy
- type QueryExecutionProxy
Constants ¶
This section is empty.
Variables ¶
var ( // ProjectId is a variable so that unit tests can override it to ensures that test requests are not routed to // the live project! See https://firebase.google.com/docs/emulator-suite/connect_firestore ProjectId string // UnitTestNewCartServiceError should be returned by NewCartService if we are running unit tests // and unitTestNewCartServiceError is not nil. UnitTestNewCartServiceError error )
Functions ¶
This section is empty.
Types ¶
type CartService ¶
type CartService struct { pbcart.UnimplementedCartAPIServer // FsClient is the GCP Firestore client - it is thread safe and can be reused concurrently FsClient *firestore.Client // contains filtered or unexported fields }
CartService is a structure class with methods that implements the cart.OrderAPIServer gRPC API storing the data for shopping carts in a Google Cloud Firestore document collection.
func NewCartService ¶
func NewCartService() (*CartService, error)
NewCartService is a factory method returning an instance of our shopping cart service.
func (*CartService) AbandonShoppingCart ¶
func (cs *CartService) AbandonShoppingCart(ctx context.Context, req *pbcart.AbandonShoppingCartRequest) (*pbcart.AbandonShoppingCartResponse, error)
AbandonShoppingCart explicitly abandons a shopping cart in response to a user request (as against the system cancelling a cart that has gone unused for some period of time).
func (*CartService) AddItemToShoppingCart ¶
func (cs *CartService) AddItemToShoppingCart(ctx context.Context, req *pbcart.AddItemToShoppingCartRequest) (*pbcart.AddItemToShoppingCartResponse, error)
AddItemToShoppingCart adds an item to a cart.
TODO: Confirm that the item type is not already in the cart. Combine multiples / increasing quantity?? TODO: Mock handling of requirements / dependencies / rejecting invalid combinations TODO: Access control? - Cannot change if cart already closed. Cannot change if user/shopper does not match.
func (*CartService) CheckoutShoppingCart ¶
func (cs *CartService) CheckoutShoppingCart(ctx context.Context, req *pbcart.CheckoutShoppingCartRequest) (*pbcart.CheckoutShoppingCartResponse, error)
CheckoutShoppingCart submits the order / checkout the shopping cart
TODO: consider more informative structured error reporting in the response rather than as an HTTP / protocol error? TODO: Should not be able to check out cart with nothing in it and no delivery address (although delivery address might more normally be collected during checkout)
func (*CartService) CreateShoppingCart ¶
func (cs *CartService) CreateShoppingCart(ctx context.Context, req *pbcart.CreateShoppingCartRequest) (*pbcart.CreateShoppingCartResponse, error)
CreateShoppingCart returns a new shopping cart structure with a unique ID, creation time, and status assigned.
func (*CartService) GetShoppingCartByID ¶
func (cs *CartService) GetShoppingCartByID(ctx context.Context, req *pbcart.GetShoppingCartByIDRequest) (*pbcart.GetShoppingCartByIDResponse, error)
GetShoppingCartByID retrieves a cart by its UUID ID.
func (*CartService) RemoveItemFromShoppingCart ¶
func (cs *CartService) RemoveItemFromShoppingCart(ctx context.Context, req *pbcart.RemoveItemFromShoppingCartRequest) (*pbcart.RemoveItemFromShoppingCartResponse, error)
RemoveItemFromShoppingCart removes an item from the cart.
func (*CartService) SetDeliveryAddress ¶
func (cs *CartService) SetDeliveryAddress(ctx context.Context, req *pbcart.SetDeliveryAddressRequest) (*pbcart.SetDeliveryAddressResponse, error)
SetDeliveryAddress adds (or replaces) the delivery address to be used for physical cart items.
type DocIteratorProxy ¶
type DocIteratorProxy struct { DocumentIteratorProxy // contains filtered or unexported fields }
DocIteratorProxy is the production (i.e. non-unit test) implementation of the DocumentIteratorProxy interface.
It is returned by calls to the CollRefProxy Documents function, itself a proxy implementation of firestore.CollectionRef.
func (*DocIteratorProxy) Next ¶
func (p *DocIteratorProxy) Next(target interface{}) error
Next returns the next result. Its second return value is iterator.Done if there are no more results. Once Next returns Done, all subsequent calls will return Done.
func (*DocIteratorProxy) Stop ¶
func (p *DocIteratorProxy) Stop()
Stop stops the iterator, freeing its resources. Always call Stop when you are done with a DocumentIterator. It is not safe to call Stop concurrently with Next.
type DocRefProxy ¶
type DocRefProxy struct {
DocumentRefProxy
}
DocRefProxy is the production (i.e. non-unit test) implementation of the DocumentRefProxy interface. NewCartService configures it as the default in new CartService structure constructions.
func (*DocRefProxy) Create ¶
func (p *DocRefProxy) Create(doc *firestore.DocumentRef, ctx context.Context, data interface{}) (*firestore.WriteResult, error)
Create is a direct pass through to the firestore.DocumentRef Create function. We use this rather than calling the firestore.DocumentRef function directly so that we can replace this implementation with one that allows errors to be inserted into the response when executing unit tests.
func (*DocRefProxy) Delete ¶
func (p *DocRefProxy) Delete(doc *firestore.DocumentRef, ctx context.Context) (*firestore.WriteResult, error)
Delete is a direct pass through to the firestore.DocumentRef Delete function. We use this rather than calling the firestore.DocumentRef function directly so that we can replace this implementation with one that allows errors to be inserted into the response when executing unit tests.
func (*DocRefProxy) Get ¶
func (p *DocRefProxy) Get(doc *firestore.DocumentRef, ctx context.Context) (*firestore.DocumentSnapshot, error)
Get is a direct pass through to the firestore.DocumentRef Get function. We use this rather than calling the firestore.DocumentRef function directly so that we can replace this implementation with one that allows errors to be inserted into the response when executing unit tests.
func (*DocRefProxy) Set ¶
func (p *DocRefProxy) Set(doc *firestore.DocumentRef, ctx context.Context, data interface{}) (*firestore.WriteResult, error)
Set is a direct pass through to the firestore.DocumentRef Set function. We use this rather than calling the firestore.DocumentRef function directly so that we can replace this implementation with one that allows errors to be inserted into the response when executing unit tests.
func (*DocRefProxy) TransactionalCreate ¶
func (p *DocRefProxy) TransactionalCreate(doc *firestore.DocumentRef, tx *firestore.Transaction, data interface{}) error
TransactionalCreate is a direct pass through to the firestore.Transaction Create function. We use this rather than calling the firestore.Transaction function directly so that we can replace this implementation with one that allows errors to be inserted into the response when executing unit tests.
func (*DocRefProxy) Update ¶
func (p *DocRefProxy) Update(doc *firestore.DocumentRef, ctx context.Context, updates []firestore.Update) (*firestore.WriteResult, error)
type DocSnapProxy ¶
type DocSnapProxy struct {
DocumentRefProxy
}
DocSnapProxy is the production (i.e. non-unit test) implementation of the DocumentSnapshotProxy interface. NewCartService configures it as the default in new CartService structure constructions.
func (*DocSnapProxy) DataTo ¶
func (p *DocSnapProxy) DataTo(snap *firestore.DocumentSnapshot, target interface{}) error
DataTo is a direct pass through to the firestore.DocumentSnapshot DataTo function. We use this rather than calling the firestore.DocumentSnapshot function directly so that we can replace this implementation with one that allows errors to be inserted into the response when executing unit tests.
type DocumentIteratorProxy ¶
type DocumentIteratorProxy interface { Next(target interface{}) error Stop() }
DocumentIteratorProxy defines the interface for a swappable junction that will allow us to maximize unit test coverage by intercepting calls to firestore.DocumentIterator methods and having them return either mock errors or document and/or iterator proxies. The default production implementation of the interface will add a couple of nanoseconds of delay to normal operation but that extra test coverage is worth the price.
See https://pkg.go.dev/cloud.google.com/go/firestore#DocumentIterator
type DocumentRefProxy ¶
type DocumentRefProxy interface { Create(doc *firestore.DocumentRef, ctx context.Context, data interface{}) (*firestore.WriteResult, error) TransactionalCreate(doc *firestore.DocumentRef, tx *firestore.Transaction, data interface{}) error Get(doc *firestore.DocumentRef, ctx context.Context) (*firestore.DocumentSnapshot, error) Set(doc *firestore.DocumentRef, ctx context.Context, data interface{}) (*firestore.WriteResult, error) Update(doc *firestore.DocumentRef, ctx context.Context, updates []firestore.Update) (*firestore.WriteResult, error) Delete(doc *firestore.DocumentRef, ctx context.Context) (*firestore.WriteResult, error) }
DocumentRefProxy defines the interface for a swappable junction that will allow us to maximize unit test coverage by intercepting calls to firestore.DocumentRef methods and having them return mock errors. The default production implementation of the interface will add a couple of nanoseconds of delay to normal operation but that extra test coverage is worth the price.
See https://pkg.go.dev/cloud.google.com/go/firestore#DocumentRef
type DocumentSnapshotProxy ¶
type DocumentSnapshotProxy interface {
DataTo(snap *firestore.DocumentSnapshot, target interface{}) error
}
DocumentSnapshotProxy defines the interface for a swappable junction that will allow us to maximize unit test coverage by intercepting calls to firestore.DocumentSnapshot methods and having them return mock errors. The default production implementation of the interface will add a couple of nanoseconds of delay to normal operation but that extra test coverage is worth the price.
See https://pkg.go.dev/cloud.google.com/go/firestore#DocumentSnapshot
type ItemCollGetterProxy ¶
type ItemCollGetterProxy struct { ItemCollectionGetterProxy // FsClient is the GCP Firestore client - it is thread safe and can be reused concurrently FsClient *firestore.Client }
ItemCollGetterProxy is the production (i.e. non-unit test) implementation of the ItemCollectionGetterProxy interface. NewCartService configures it as the default in new CartService structure constructions.
func (*ItemCollGetterProxy) Items ¶
func (p *ItemCollGetterProxy) Items(path string) ItemsCollectionProxy
Items returns a collection reference proxy that allows the items of the given collection to be retrieved from Firestore.
type ItemCollectionGetterProxy ¶
type ItemCollectionGetterProxy interface {
Items(path string) ItemsCollectionProxy
}
ItemCollectionGetterProxy defines an interface that a Firestore client service can use to obtain an ItemsCollectionProxy for a given collection path. Unit tests may substitute an alternative implementation this interface in order to be able to insert errors etc. into the responses of the ItemsCollectionProxy that the ItemCollectionGetterProxy returns.
type ItemsCollProxy ¶
type ItemsCollProxy struct { ItemsCollectionProxy // contains filtered or unexported fields }
ItemsCollProxy is the production (i.e. non-unit test) implementation of the ItemsCollectionProxy interface.
See https://pkg.go.dev/cloud.google.com/go/firestore#CollectionRef
func (*ItemsCollProxy) GetAll ¶
func (p *ItemsCollProxy) GetAll(ctx context.Context) DocumentIteratorProxy
GetAll is a wrapper around the firestore.CollectionRef Documents function (actually the firestore.Query Documents function) that will return an iterator over the items from a Firestore collection or query representation.
type ItemsCollectionProxy ¶
type ItemsCollectionProxy interface {
GetAll(ctx context.Context) DocumentIteratorProxy
}
ItemsCollectionProxy defines the interface for a swappable junction that will allow us to maximize unit test coverage by wrapping calls to the firestore.CollectionRef Documents method and so allowing unit test implementations to return either mock errors, mock documents, or mock iterator proxies. The default production implementation of the interface will add a couple of nanoseconds of delay to normal operation but that extra test coverage is worth the price.
See https://pkg.go.dev/cloud.google.com/go/firestore#CollectionRef
type QueryExecProxy ¶
type QueryExecProxy struct {
QueryExecutionProxy
}
QueryExecProxy implements a wrapper function around firestore.Query that will return an iterator over items that match the query.
func (*QueryExecProxy) Documents ¶
func (q *QueryExecProxy) Documents(ctx context.Context, query firestore.Query) DocumentIteratorProxy
Documents returns a DocumentIteratorProxy wrapping the results of the given query. Unit test implementations of this function can be programmed to return an iterator that can insert errors into the flow but this production ready implementation returns a transparent passthrough iterator.
type QueryExecutionProxy ¶
type QueryExecutionProxy interface {
Documents(ctx context.Context, query firestore.Query) DocumentIteratorProxy
}
QueryExecutionProxy defines an interface that a Firestore client service can use to obtain an DocumentIteratorProxy to walk the results of given for a given firestore.Query. Unit tests may substitute an alternative implementation this interface in order to be able to insert errors etc. into the responses of the DocumentIteratorProxy that the QueryExecutionProxy returns.