Pub Build Status codecov.io documentation


Fluri is a fluent URI library for Dart built to make URI mutation easy.

The dart:core.Uri class provides an immutable representation of URIs, which makes it difficult to incrementally build them or update them at a later time. If you wanted to build a long URI from the individual pieces, you would do something like this:

Uri uri = new Uri(
  scheme: 'https',
  host: 'example.com',
  path: 'path/to/resource'

If you later wanted to update the path and add a query parameter, you'd have to do this:

uri = uri.replace(
  path: 'new/path',
  query: 'foo=true'

Now let's say you want update the query without losing what you already have:

Map query = new Map.from(uri.queryParameters);
query['bar'] = '10';
uri = uri.replace(queryParameters: query);

As you can see, incremental or fluent-style URI mutations become a hassle with the core Uri class.

With fluri, the above interactions are easy:

import 'package:fluri/fluri.dart';

Fluri fluri = new Fluri()
  ..scheme = 'https'
  ..host = 'example.com'
  ..path = 'path/to/resource';

  ..path = 'new/path'
  ..query = 'foo=true';

fluri.updateQuery({'bar': '10'});

Additional methods like appendToPath and setQueryParam make it easy to build on top of a base URL:

import 'package:fluri/fluri.dart';

Fluri base = new Fluri('https://example.com/base/');

Fluri fluri = new Fluri.from(base)
  ..setQueryParam('count', '10');

Fluri also supports multi-value parameters. To access the query parameters as Map<String, List<String>>, use queryParametersAll (just like the Uri class):

var fluri = new Fluri('/resource?format=json&format=text');
print(fluri.queryParameters); // {'format': 'text'}
print(fluri.queryParametersAll); // {'format': ['json', 'text']}

To set a single query parameter to multiple values:

var fluri = new Fluri('/resource');
fluri.setQueryParam('format', ['json', 'text']);
print(fluri.queryParametersAll); // {'format': ['json', 'text']}

Using setQueryParam will always replace existing values:

var fluri = new Fluri('/resource');
fluri.setQueryParam('format', ['json', 'text']);
fluri.setQueryParam('format', ['binary', 'text']);
print(fluri.queryParametersAll); // {'format': ['binary', 'text']}

You can use the queryParametersAll setter to set the entire query with multi-value param support:

var fluri = new Fluri('/resource');
fluri.queryParametersAll = {'format': ['json', 'text'], 'count': ['5']}
print(fluri.queryParametersAll); // {'format': ['json', 'text'], 'count': ['5']}

Again, if you need to preserve existing query parameters, you can use the updateQuery method to do so. Set mergeValues: true and any values that you provide will be merged with existing values:

var fluri = new Fluri('/resource?format=json');
fluri.updateQuery({'format': ['binary', 'text'], 'count': '5'}, mergeValues: true);
print(fluri.queryParametersAll); // {'format': ['binary', 'json', 'text'], 'count': ['5']}

Dart SDK

As of version 1.2.0 of the fluri package, the minimum required Dart SDK version is 1.15.0.

Versioning and Stability

This library follows semver to the best of our interpretation of it. We want this library to be a stable dependency that’s easy to keep current. A good explanation of the versioning scheme that we intend to follow can be seen here from React.js:


In short: our goal is for every major release to be backwards compatible with the previous major version, giving consumers a lifespan of two major versions to deal with deprecations.


This project leverages the dart_dev package for most of its tooling needs, including static analysis, code formatting, running tests, collecting coverage, and serving examples. Check out the dart_dev readme for more information.



A fluent URI mutation library.