diff --git a/MIGRATE.md b/MIGRATE.md index 11dadb2..9311404 100644 --- a/MIGRATE.md +++ b/MIGRATE.md @@ -97,3 +97,14 @@ The preferred import method includes the major version tag. ```go import "github.com/graph-gophers/dataloader/v6" ``` + +## Upgrade from v6 to v7 + +[Generics](https://go.dev/doc/tutorial/generics) support has been added. +With this update, you can now write more type-safe code. + +Use the major version tag in the import path. + +```go +import "github.com/graph-gophers/dataloader/v7" +``` diff --git a/README.md b/README.md index 8a74511..00685eb 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,15 @@ This is an implementation of [Facebook's DataLoader](https://github.com/facebook/dataloader) in Golang. ## Install -`go get -u github.com/graph-gophers/dataloader` +`go get -u github.com/graph-gophers/dataloader/v7` ## Usage ```go // setup batch function - the first Context passed to the Loader's Load // function will be provided when the batch function is called. -batchFn := func(ctx context.Context, keys dataloader.Keys) []*dataloader.Result { - var results []*dataloader.Result +// this function is registered with the Loader, and the key and value are fixed using generics. +batchFn := func(ctx context.Context, keys []int) []*dataloader.Result[*User] { + var results []*dataloader.Result[*User] // do some async work to get data for specified keys // append to this list resolved values return results @@ -32,7 +33,7 @@ loader := dataloader.NewBatchedLoader(batchFn) * The first context passed to Load is the object that will be passed * to the batch function. */ -thunk := loader.Load(context.TODO(), dataloader.StringKey("key1")) // StringKey is a convenience method that make wraps string to implement `Key` interface +thunk := loader.Load(context.TODO(), 5) result, err := thunk() if err != nil { // handle data error @@ -51,3 +52,7 @@ This implementation contains a very basic cache that is intended only to be used ## Examples There are a few basic examples in the example folder. + +## See also +- [TRACE](TRACE.md) +- [MIGRATE](MIGRATE.md) diff --git a/TRACE.md b/TRACE.md index ea43760..e533e3a 100644 --- a/TRACE.md +++ b/TRACE.md @@ -12,68 +12,72 @@ import ( "context" "strings" - exp "go.opencensus.io/examples/exporter" - "github.com/nicksrandall/dataloader" + "github.com/graph-gophers/dataloader/v7" + exp "go.opencensus.io/examples/exporter" "go.opencensus.io/trace" ) +type User struct { + ID string +} + // OpenCensusTracer Tracer implements a tracer that can be used with the Open Tracing standard. type OpenCensusTracer struct{} // TraceLoad will trace a call to dataloader.LoadMany with Open Tracing -func (OpenCensusTracer) TraceLoad(ctx context.Context, key dataloader.Key) (context.Context, dataloader.TraceLoadFinishFunc) { +func (OpenCensusTracer) TraceLoad(ctx context.Context, key string) (context.Context, dataloader.TraceLoadFinishFunc[*User]) { cCtx, cSpan := trace.StartSpan(ctx, "Dataloader: load") cSpan.AddAttributes( - trace.StringAttribute("dataloader.key", key.String()), + trace.StringAttribute("dataloader.key", key), ) - return cCtx, func(thunk dataloader.Thunk) { + return cCtx, func(thunk dataloader.Thunk[*User]) { // TODO: is there anything we should do with the results? cSpan.End() } } // TraceLoadMany will trace a call to dataloader.LoadMany with Open Tracing -func (OpenCensusTracer) TraceLoadMany(ctx context.Context, keys dataloader.Keys) (context.Context, dataloader.TraceLoadManyFinishFunc) { +func (OpenCensusTracer) TraceLoadMany(ctx context.Context, keys []string) (context.Context, dataloader.TraceLoadManyFinishFunc[*User]) { cCtx, cSpan := trace.StartSpan(ctx, "Dataloader: loadmany") cSpan.AddAttributes( - trace.StringAttribute("dataloader.keys", strings.Join(keys.Keys(), ",")), + trace.StringAttribute("dataloader.keys", strings.Join(keys, ",")), ) - return cCtx, func(thunk dataloader.ThunkMany) { + return cCtx, func(thunk dataloader.ThunkMany[*User]) { // TODO: is there anything we should do with the results? cSpan.End() } } // TraceBatch will trace a call to dataloader.LoadMany with Open Tracing -func (OpenCensusTracer) TraceBatch(ctx context.Context, keys dataloader.Keys) (context.Context, dataloader.TraceBatchFinishFunc) { +func (OpenCensusTracer) TraceBatch(ctx context.Context, keys []string) (context.Context, dataloader.TraceBatchFinishFunc[*User]) { cCtx, cSpan := trace.StartSpan(ctx, "Dataloader: batch") cSpan.AddAttributes( - trace.StringAttribute("dataloader.keys", strings.Join(keys.Keys(), ",")), + trace.StringAttribute("dataloader.keys", strings.Join(keys, ",")), ) - return cCtx, func(results []*dataloader.Result) { + return cCtx, func(results []*dataloader.Result[*User]) { // TODO: is there anything we should do with the results? cSpan.End() } } -func batchFunc(ctx context.Context, keys dataloader.Keys) []*dataloader.Result { - // ...loader logic goes here +func batchFunc(ctx context.Context, keys []string) []*dataloader.Result[*User] { + // ...loader logic goes here } -func main(){ - //initialize an example exporter that just logs to the console - trace.ApplyConfig(trace.Config{ +func main() { + //initialize an example exporter that just logs to the console + trace.ApplyConfig(trace.Config{ DefaultSampler: trace.AlwaysSample(), }) - trace.RegisterExporter(&exp.PrintExporter{}) - // initialize the dataloader with your new tracer backend - loader := dataloader.NewBatchedLoader(batchFunc, dataloader.WithTracer(OpenCensusTracer{})) - // initialize a context since it's not receiving one from anywhere else. - ctx, span := trace.StartSpan(context.TODO(), "Span Name") - defer span.End() - // request from the dataloader as usual - value, err := loader.Load(ctx, dataloader.StringKey(SomeID))() - // ... + trace.RegisterExporter(&exp.PrintExporter{}) + // initialize the dataloader with your new tracer backend + loader := dataloader.NewBatchedLoader(batchFunc, dataloader.WithTracer[string, *User](OpenCensusTracer{})) + // initialize a context since it's not receiving one from anywhere else. + ctx, span := trace.StartSpan(context.TODO(), "Span Name") + defer span.End() + // request from the dataloader as usual + value, err := loader.Load(ctx, SomeID)() + // ... } ```