11# DataLoader
2+
3+ [ ![ ] ( https://img.shields.io/badge/License-MIT-blue.svg?style=flat )] ( https://tldrlegal.com/license/mit-license )
4+ [ ![ ] ( https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FGraphQLSwift%2FDataLoader%2Fbadge%3Ftype%3Dswift-versions )] ( https://swiftpackageindex.com/GraphQLSwift/DataLoader )
5+ [ ![ ] ( https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FGraphQLSwift%2FDataLoader%2Fbadge%3Ftype%3Dplatforms )] ( https://swiftpackageindex.com/GraphQLSwift/DataLoader )
6+
27DataLoader is a generic utility to be used as part of your application's data fetching layer to provide a simplified and consistent API over various remote data sources such as databases or web services via batching and caching.
38
49This is a Swift version of the Facebook [ DataLoader] ( https://github.com/facebook/dataloader ) .
510
6- [ ![ Swift] [ swift-badge ]] [ swift-url ]
7- [ ![ License] [ mit-badge ]] [ mit-url ]
8-
911## Gettings started 🚀
1012
1113Include this repo in your ` Package.swift ` file.
@@ -40,7 +42,7 @@ let future2 = try userLoader.load(key: 2, on: eventLoopGroup)
4042let future3 = try userLoader.load (key : 1 , on : eventLoopGroup)
4143```
4244
43- The example above will only fetch two users, because the user with key ` 1 ` is present twice in the list.
45+ The example above will only fetch two users, because the user with key ` 1 ` is present twice in the list.
4446
4547### Load multiple keys
4648There is also a method to load multiple keys at once
@@ -50,14 +52,14 @@ try userLoader.loadMany(keys: [1, 2, 3], on: eventLoopGroup)
5052
5153### Execution
5254By default, a DataLoader will wait for a short time from the moment ` load ` is called to collect keys prior
53- to running the ` batchLoadFunction ` and completing the ` load ` futures. This is to let keys accumulate and
54- batch into a smaller number of total requests. This amount of time is configurable using the ` executionPeriod `
55+ to running the ` batchLoadFunction ` and completing the ` load ` futures. This is to let keys accumulate and
56+ batch into a smaller number of total requests. This amount of time is configurable using the ` executionPeriod `
5557option:
5658
5759``` swift
5860let myLoader = DataLoader< String , String > (
5961 options : DataLoaderOptions (executionPeriod : .milliseconds (50 )),
60- batchLoadFunction : { keys in
62+ batchLoadFunction : { keys in
6163 self .someBatchLoader (keys : keys).map { DataLoaderFutureValue.success ($0 ) }
6264 }
6365)
@@ -66,10 +68,10 @@ let myLoader = DataLoader<String, String>(
6668Longer execution periods reduce the number of total data requests, but also reduce the responsiveness of the
6769` load ` futures.
6870
69- If desired, you can manually execute the ` batchLoadFunction ` and complete the futures at any time, using the
71+ If desired, you can manually execute the ` batchLoadFunction ` and complete the futures at any time, using the
7072` .execute() ` method.
7173
72- Scheduled execution can be disabled by setting ` executionPeriod ` to ` nil ` , but be careful - you * must* call ` .execute() `
74+ Scheduled execution can be disabled by setting ` executionPeriod ` to ` nil ` , but be careful - you * must* call ` .execute() `
7375manually in this case. Otherwise, the futures will never complete!
7476
7577### Disable batching
@@ -78,10 +80,10 @@ In this case, the `batchLoadFunction` will be invoked immediately when a key is
7880
7981
8082## Caching 💰
81- DataLoader provides a memoization cache. After ` .load() ` is called with a key, the resulting value is cached
83+ DataLoader provides a memoization cache. After ` .load() ` is called with a key, the resulting value is cached
8284for the lifetime of the DataLoader object. This eliminates redundant loads.
8385
84- In addition to relieving pressure on your data storage, caching results also creates fewer objects which may
86+ In addition to relieving pressure on your data storage, caching results also creates fewer objects which may
8587relieve memory pressure on your application:
8688
8789``` swift
@@ -132,15 +134,15 @@ userLoader.load(key: 4, on: eventLoopGroup)
132134
133135### Caching Errors
134136
135- If a batch load fails (that is, a batch function throws or returns a DataLoaderFutureValue.failure(Error)),
137+ If a batch load fails (that is, a batch function throws or returns a DataLoaderFutureValue.failure(Error)),
136138then the requested values will not be cached. However if a batch
137139function returns an ` Error ` instance for an individual value, that ` Error ` will
138140be cached to avoid frequently loading the same ` Error ` .
139141
140142In some circumstances you may wish to clear the cache for these individual Errors:
141143
142144``` swift
143- userLoader.load (key : 1 , on : eventLoopGroup).whenFailure { error in
145+ userLoader.load (key : 1 , on : eventLoopGroup).whenFailure { error in
144146 if (/* determine if should clear error */ ) {
145147 userLoader.clear (key : 1 );
146148 }
@@ -165,7 +167,7 @@ For example:
165167``` swift
166168let myLoader = DataLoader< String , String > (
167169 options : DataLoaderOptions (cachingEnabled : false ),
168- batchLoadFunction : { keys in
170+ batchLoadFunction : { keys in
169171 self .someBatchLoader (keys : keys).map { DataLoaderFutureValue.success ($0 ) }
170172 }
171173)
@@ -193,7 +195,7 @@ let myLoader = DataLoader<String, String>(batchLoadFunction: { keys in
193195## Using with GraphQL 🎀
194196
195197DataLoader pairs nicely well with [ GraphQL] ( https://github.com/GraphQLSwift/GraphQL ) and
196- [ Graphiti] ( https://github.com/GraphQLSwift/Graphiti ) . GraphQL fields are designed to be
198+ [ Graphiti] ( https://github.com/GraphQLSwift/Graphiti ) . GraphQL fields are designed to be
197199stand-alone functions. Without a caching or batching mechanism,
198200it's easy for a naive GraphQL server to issue new database requests each time a
199201field is resolved.
@@ -220,7 +222,7 @@ Consider the following GraphQL request:
220222Naively, if ` me ` , ` bestFriend ` and ` friends ` each need to request the backend,
221223there could be at most 12 database requests!
222224
223- By using DataLoader, we could batch our requests to a ` User ` type, and
225+ By using DataLoader, we could batch our requests to a ` User ` type, and
224226only require at most 4 database requests, and possibly fewer if there are cache hits.
225227Here's a full example using Graphiti:
226228
@@ -230,11 +232,11 @@ struct User : Codable {
230232 let name: String
231233 let bestFriendID: Int
232234 let friendIDs: [Int ]
233-
235+
234236 func getBestFriend (context : UserContext, arguments : NoArguments, group : EventLoopGroup) throws -> EventLoopFuture<User> {
235237 return try context.userLoader .load (key : user.bestFriendID , on : group)
236238 }
237-
239+
238240 struct FriendArguments {
239241 first: Int
240242 }
@@ -271,7 +273,7 @@ struct UserAPI : API {
271273 Argument (" first" , at : .\first)
272274 }
273275 }
274-
276+
275277 Query {
276278 Field (" me" , at : UserResolver.hero , as : User.self )
277279 }
@@ -299,14 +301,6 @@ swiftformat .
299301
300302## Acknowledgements 👏
301303
302- This library is entirely a Swift version of Facebooks [ DataLoader] ( https://github.com/facebook/dataloader ) .
303- Developed by [ Lee Byron] ( https://github.com/leebyron ) and [ Nicholas Schrock] ( https://github.com/schrockn )
304+ This library is entirely a Swift version of Facebooks [ DataLoader] ( https://github.com/facebook/dataloader ) .
305+ Developed by [ Lee Byron] ( https://github.com/leebyron ) and [ Nicholas Schrock] ( https://github.com/schrockn )
304306from [ Facebook] ( https://www.facebook.com/ ) .
305-
306-
307-
308- [ swift-badge ] : https://img.shields.io/badge/Swift-5.2-orange.svg?style=flat
309- [ swift-url ] : https://swift.org
310-
311- [ mit-badge ] : https://img.shields.io/badge/License-MIT-blue.svg?style=flat
312- [ mit-url ] : https://tldrlegal.com/license/mit-license
0 commit comments