Do you have code that looks like this?
var myServerUrl = "http://localhost/foo"; // local server
//var myServerUrl = "http://awesomeapp.com/foo"; // real server
Do you wish you could load settings from a config file, like this yaml below:
# local server config.yaml
myServerUrl: http://localhost/foo
or
# real server config.yaml
myServerUrl: http://awesomeapp.com/foo
Now you can, with the same syntax whether you're running Dart in the browser, or running Dart on the server.
1. Add a dependency to pubspec.yaml
for dart_config
:
dependencies
dart_config: any
2. If you are running in the browser, add the following code to your app to load config information from the server:
import 'package:dart_config/default_browser.dart';
main() {
loadConfig().then(
(Map config) {
print(config["myServerUrl"]);
// continue with your app here!
},
onError: (error) => print(error));
}
2. If you are running in the server, add the following code to your app to load config information from the filesystem:
import 'package:dart_config/default_server.dart';
main() {
loadConfig().then(
(Map config) {
print(config["myServerUrl"]);
// continue with your app here!
},
onError: (error) => print(error));
}
Both the client and server code looks for a file called config.yaml
, loads
it from the current folder (or current browser path), parses it, and returns
it to your app as a map of key/value pairs (the values may also be maps
themselves).
Take a look at test/test_default_browser.dart
and
test/test_default_server.dart
, and the associated config.yaml
files.
Of course you want more control! The loadConfig()
function actually takes
an optional filename
parameter, which defaults to config.yaml
- but you
can provide a different filename / path if you want.
Of course you do. The default_browser
and default_server
libraries are
just opinionated implementations. Behind the scenes, they are calling code that
looks similar to this:
var config = new Config(filename,
new ConfigFilesystemLoader(),
new YamlConfigParser());
return config.readConfig(); // returns a Future<Map>
The Config
class has a single constructor, which takes three parameters.
The first parameter is the location of the config file. The second is an
implementation of ConfigLoader
, and the third is an implementation of
ConfigParser
(this is a typical dependency injection pattern)
The dart_config
library comes (at the moment) with two ConfigLoader
implementations and two ConfigParser implementations:
ConfigFilesystemLoader
ConfigHttpRequestLoader
YamlConfigParser
JsonConfigParser
You can use any combination of loader and parser. At its core, the config system needs to know how to load a config file and how to parse a config file. It really is no more complex than that.
Take a look at the three files: tests.dart
(a VM independant suite of tests),
and the test_browser.dart
and test_server.dart
, which run the same set of
tests found in tests.dart
both in the browser and on the server. The only
differences are ConfigLoader
implementation, and the path to the config files.
No problem - simply implement your own version of ConfigLoader
- there's only
one method: Future<String> loadConfig(pathOrUrl)
- just return the contents
of the config file in the Future, and it will get passed into whatever
parser you specify.
No problem again - simply implement your own version of ConfogParser
- there's
only one method: Future<Map<String,Object>> parse(String configText)
- just
parse the String contents that the ConfigLoader has loaded into a Map, and
return it in a Future.
Great! - Please share :) - create your own pub packaged containing loaders and/ or parsers, or clone this library and issue pull requests.
Some ideas (that I might work on if someone else doesn't get there first):
- TOML parser
- Key=value pair parser
- Server-side HttpClient configLoader - load config files from a remote url
Raise an issue on github and I'll take a look, or even better, create a pull request with a failing unit test or even a fix?
StackOverflow is a great place for that. Make sure you use the dart tag, and it will find its way to me, or others that are very knowledgeable.