scala-uri is a small Scala library that helps you work with URIs. It has the following features:
- A DSL for building URIs
- A parser to parse URIs from Strings.
- Can be used outside a servlet environment as it has zero dependencies on the servlet spec or existing web frameworks.
- Ability to replace and remove query string parameters
- Support for custom encoding such as encoding spaces as pluses
- Support for protocol relative urls
To include it in your SBT project from maven central:
"com.github.theon" %% "scala-uri" % "0.3.5"import com.github.theon.uri.Uri._
val uri = "http://theon.github.com/scala-uri" ? ("p1" -> "one") & ("p2" -> 2) & ("p3" -> true)
uri.toString //This is: http://theon.github.com/scala-uri?p1=one&p2=2&p3=trueBy importing com.github.theon.uri.Uri._, Strings can be implicitly converted to URIs.
To add query string parameters, use either the ? or & method and pass a Tuple2 as an argument. The first value in the Tuple is a name of the query string parameter, the second is the value. If a parameter value is an Option, it will only be rendered provided it is not None.
To explicitly create a Uri, you can use the following constructors:
val uri = Uri("http", "theon.github.com", "/scala-uri") //Absolute URI
val uri = Uri("/scala-uri") //Relative URIProvided you have the import com.github.theon.uri.Uri._, Strings will be implicitly parsed into Uri instances:
import com.github.theon.uri.Uri._
val uri:Uri = "http://theon.github.com/scala-uri?param1=1¶m2=2"However, if you prefer, you can call parseUri() explicitly:
import com.github.theon.uri.Uri.parseUri
val uri = parseUri("http://theon.github.com/scala-uri?param1=1¶m2=2")You can specify an Option as the value of a query string parameter. It will get rendered if it is Some(x) and won't get rendered if it is None
import com.github.theon.uri.Uri._
val uri = "http://theon.github.com/scala-uri" ? ("param1" -> Some("1")) & ("param2" -> None)
uri.toString //This is: http://theon.github.com/scala-uri?param1=1By Default, scala-uri will URL percent encode paths and query string parameters. To prevent this, you can call the uri.toStringRaw method:
import com.github.theon.uri.Uri._
val uri = "http://example.com/path with space" ? ("param" -> "üri")
uri.toString //This is: http://example.com/path%20with%20space?param=%C3%BCri
uri.toStringRaw //This is: http://example.com/path with space?param=üriThe default behaviour with scala uri, is to encode spaces as %20, however if you instead wish them to be encoded as the + symbol, then simply add the following implicit val to your code:
import com.github.theon.uri.Uri._
import com.github.theon.uri.Encoders._
implicit val encoder = PercentEncoder + EncodeSpaceAsPlus
val uri:Uri = "http://theon.github.com/uri with space"
uri.toString //This is http://theon.github.com/uri+with+spaceIf you would like to do some custom encoding for specific characters, you can use the EncodeCharAs encoder.
import com.github.theon.uri.Uri._
import com.github.theon.uri.Encoders._
implicit val encoder = PercentEncoder + EncodeCharAs(' ', "_")
val uri:Uri = "http://theon.github.com/uri with space"
uri.toString //This is http://theon.github.com/uri_with_spaceIf you wish to replace all existing query string parameters with a given name, you can use the uri.replaceParams() method:
import com.github.theon.uri.Uri._
val uri = "http://example.com/path" ? ("param" -> "1")
val newUri = uri.replaceParams("param", "2")
newUri.toString //This is: http://example.com/path?param=2If you wish to remove all existing query string parameters with a given name, you can use the uri.removeParams() method:
import com.github.theon.uri.Uri._
val uri = "http://example.com/path" ? ("param" -> "1") & ("param2" -> "2")
val newUri = uri.removeParams("param")
newUri.toString //This is: http://example.com/path?param2=2To get the query string parameters as a Map[String,List[String]] you can do the following:
import com.github.theon.uri.Uri._
val uri = "http://example.com/path" ? ("param" -> "1") & ("param2" -> 2)
uri.query.params //This is: Map(param -> List(1), param2 -> List(2))Protocol Relative URLs are supported in scala-uri. A Uri object with a protocol of None, but a host of Some(x) will be considered a protocol relative URL.
import com.github.theon.uri.Uri._
val uri:Uri = "//example.com/path"
uri.scheme //This is: None
uri.host //This is: Some("example.com")scala-uri is currently built with support for scala 2.9.2 and 2.10.0
Release builds are available in maven central. Just add the following dependency:
"com.github.theon" %% "scala-uri" % "0.3.5"For the latest snapshot builds, add the Sonatype OSS repo to your SBT build configuration:
resolvers += "Sonatype OSS" at "http://oss.sonatype.org/content/public"Add the following dependency:
"com.github.theon" %% "scala-uri" % "0.3.6-SNAPSHOT"Contributions to scala-uri are always welcome. Good ways to contribute include:
- Raising bugs and feature requests
- Fixing bugs and developing new features (I will attempt to merge in pull requests ASAP)
- Improving the performance of
scala-uri. See the Performance Tests project for details of how to run thescala-uriperformance benchmarks.
The unit tests can be run from the sbt console by running the test command! Checking the unit tests all pass before sending pull requests will be much appreciated.
Generate code coverage reports from the sbt console by running the scct:test command. The HTML reports should be generated at target/scala-2.10/coverage-report/index.html. Ideally pull requests shouldn't significantly decrease code coverage, but it's not the end of the world if they do. Contributions with no tests are better than no contributions :)
For the scala-uri performance tests head to the scala-uri-benchmarks github project
scala-uri is open source software released under the Apache 2 License.

