diff --git a/example/.swerve/config.yml b/example/.swerve/config.yml
index f4bac0706d1e221dcc958508005c809c446048fd..b6f87d200c03b3ce036855605d449365f9e97853 100644
--- a/example/.swerve/config.yml
+++ b/example/.swerve/config.yml
@@ -2,16 +2,17 @@ field_handling: Log
 file_handling: File
 server:
   port: 9000
-requests:
-  - /users/@user_id : scripts/get_user_by_id.dyon
-  - /users :
+routes:
+  - route: /users/@user_id
+    script: scripts/get_user_by_id.dyon
+  - route: /users
+    response:
       failure_rate: 5
-      response_headers:
+      headers:
         x-rate-limit: 100
         x-rate-remaining: 96
         x-rate-reset: 10/12/1990
-      response_type: application/json
-      response_body:
+      body:
         count: 2
         data:
           - id: 1
diff --git a/src/cli/config_file.rs b/src/cli/config_file.rs
index 7723ae5209ec491e3939a6f9b0c46116881003be..1718df18f6455c8bed619b02042253871c5c4fb8 100644
--- a/src/cli/config_file.rs
+++ b/src/cli/config_file.rs
@@ -7,6 +7,8 @@ use std::default::Default;
 use serde::{Deserialize, Deserializer, de};
 use std::fmt;
 use serde_yaml as yaml;
+use std::collections::HashMap;
+use cli;
 
 #[derive(Debug, Copy, Clone)]
 pub enum HandlerMethod {
@@ -52,6 +54,8 @@ pub struct SwerveConfig {
     pub file_handling: HandlerMethod,
     #[serde(default)]
     pub server: ServerOptions,
+    #[serde(default="get_empty_routes")]
+    pub routes: Vec<cli::RouteHandler>,
 }
 
 #[derive(Deserialize, Debug, Clone)]
@@ -74,12 +78,15 @@ fn get_default_address() -> String { String::from("localhost") }
 fn get_default_quiet_attr() -> bool { false }
 fn get_default_index_attr() -> bool { false }
 
+fn get_empty_routes() -> Vec<cli::RouteHandler> { vec![] }
+
 impl Default for SwerveConfig {
     fn default() -> Self {
         SwerveConfig {
             field_handling: HandlerMethod::Log,
             file_handling: HandlerMethod::Log,
             server: ServerOptions::default(),
+            routes: get_empty_routes(),
         }
     }
 }
diff --git a/src/cli/config_routes.rs b/src/cli/config_routes.rs
new file mode 100644
index 0000000000000000000000000000000000000000..62cf89dd179a19317f6e15cffc90fe4da479f3bf
--- /dev/null
+++ b/src/cli/config_routes.rs
@@ -0,0 +1,17 @@
+use std::collections::HashMap;
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct RouteHandler {
+    route: String,
+    response: Option<ResponseHandler>,
+    script: Option<String>,
+}
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct ResponseHandler {
+    failure_rate: Option<u32>,
+    #[serde(default="get_default_headers")]
+    headers: HashMap<String, String>,
+}
+
+fn get_default_headers() -> HashMap<String, String> { HashMap::new() }
diff --git a/src/cli/mod.rs b/src/cli/mod.rs
index 4993a2f81a9f290dccf6376a9afbe69b8fad9a1e..2ac3861912c08e89923a472e1838e2dfc83be11f 100644
--- a/src/cli/mod.rs
+++ b/src/cli/mod.rs
@@ -1,7 +1,9 @@
 mod cli;
 mod config_file;
+mod config_routes;
 
 pub mod gpl;
 
 pub use self::cli::{Args, USAGE};
-pub use self::config_file::{HandlerMethod, SwerveConfig};
\ No newline at end of file
+pub use self::config_file::{HandlerMethod, SwerveConfig};
+pub use self::config_routes::RouteHandler;
\ No newline at end of file
diff --git a/src/routing/request.rs b/src/routing/request.rs
index 643abe5ddd56afc24fc01c5970e9bc72b5ea768c..d1deefe714e01d0f54f220463f21cf65130c410d 100644
--- a/src/routing/request.rs
+++ b/src/routing/request.rs
@@ -2,7 +2,7 @@ use rocket::{self, Outcome, http, Response};
 use rocket::request::{FromRequest, Request};
 use rocket::http::ContentType;
 use hyper::header::Headers;
-use std::path::{Path, PathBuf};
+use std::path::{Path, PathBuf, Component};
 use std::io::BufReader;
 use std::fs::File;
 
@@ -57,3 +57,74 @@ impl rocket::response::Responder<'static> for TypedFile {
         Ok(response)
     }
 }
+
+pub struct RequestPath(pub String);
+impl <'a, 'req>FromRequest<'a, 'req> for RequestPath {
+    type Error = ();
+
+    fn from_request(request: &'a Request<'req>) -> Outcome<Self, (http::Status, ()), ()> {
+        let uri = request.uri();
+        Outcome::Success(RequestPath(String::from(uri.path())))
+    }
+}
+
+pub mod path {
+    use std::path as std_path;
+    use std::option::Option::*;
+
+    pub struct MatchablePath(pub String);
+    pub type PathMatch = (String, String);
+    pub type MatchList = Vec<PathMatch>;
+    pub type MatchResult = Option<MatchList>;
+
+    impl MatchablePath {
+        pub fn from<T>(src: T) -> Self where T: ToString {
+            MatchablePath(src.to_string())
+        }
+
+        fn path_to_vec<T: ToString>(string: T) -> Vec<String> {
+            std_path::PathBuf::from(string.to_string())
+                .components()
+                .filter_map(|c| match c {
+                    std_path::Component::Normal(cmp) => cmp.to_str()
+                        .and_then(|s| Some(String::from(s))),
+                    _ => None,
+                })
+                .collect()
+        }
+
+        pub fn matches<T>(&self, other: T) -> MatchResult where T: ToString {
+            let this_path = MatchablePath::path_to_vec(&self.0);
+            let other_path = MatchablePath::path_to_vec(other);
+
+            if this_path.len() == other_path.len() {
+                let parts_match = this_path.iter()
+                    .zip(other_path.iter())
+                    .fold(true, |acc, (this, other)| {
+                        acc && (this.starts_with("@") || this == other)
+                    });
+
+                if parts_match {
+                    Some(this_path.iter()
+                        .zip(other_path.iter())
+                        .filter_map(|(this, other)| {
+                            if this.starts_with("@") {
+                                Some((
+                                    this.chars().skip(1).collect::<String>(),
+                                    other.clone()
+                                ))
+                            } else {
+                                None
+                            }
+                        })
+                        .collect()
+                    )
+                } else {
+                    None
+                }
+            } else {
+                None
+            }
+        }
+    }
+}
diff --git a/src/routing/scripting.rs b/src/routing/scripting.rs
index 165c0070b28c4941538a6bad02dbadfcf75f02cf..02ff44d39a60e974055e15d0d78b4b409135c11e 100644
--- a/src/routing/scripting.rs
+++ b/src/routing/scripting.rs
@@ -1,8 +1,16 @@
 use scripting::run_script;
 use std::path::PathBuf;
+use routing::request;
+use server::LuaRuntime;
+use rlua::{Lua};
 
 #[get("/__testing__/run-script")]
-pub fn route_script() -> String {
+pub fn route_script(path: request::RequestPath, runtime: LuaRuntime) -> String {
+	let lua: Lua = runtime.into();
+	let doowap = path.0;
+	let foo = request::path::MatchablePath(String::from("/inspection/@id"));
+	let matches = foo.matches(String::from("/inspection/123"));
+	println!("{:?}", matches);
 	let path = PathBuf::from("example/.swerve/get_user_by_id.rhai");
 	run_script(path).unwrap_or(String::from("No script"))
 }
\ No newline at end of file
diff --git a/src/server/lua.rs b/src/server/lua.rs
index 08cd875660ace741d1753f4501e205c88553caf7..eff9e5b03a3d1d775fdfc1fe11b1967e275e6a5c 100644
--- a/src/server/lua.rs
+++ b/src/server/lua.rs
@@ -1,6 +1,34 @@
 use rlua::{Lua};
+use rocket::{self, Outcome, http, Response};
+use rocket::request::{FromRequest, Request};
+use std::convert::{Into, AsRef, AsMut};
 
-pub fn create_runtime(with_debug: bool) -> Lua {
+pub struct LuaRuntime(Lua);
+impl Into<Lua> for LuaRuntime {
+    fn into(self) -> Lua {
+        self.0
+    }
+}
+impl AsRef<Lua> for LuaRuntime {
+    fn as_ref(&self) -> &Lua {
+        &self.0
+    }
+}
+impl AsMut<Lua> for LuaRuntime {
+    fn as_mut(&mut self) -> &mut Lua {
+        &mut self.0
+    }
+}
+
+impl <'a, 'req>FromRequest<'a, 'req> for LuaRuntime {
+    type Error = ();
+
+    fn from_request(_request: &'a Request<'req>) -> Outcome<Self, (http::Status, ()), ()> {
+        Outcome::Success(create_runtime(false))
+    }
+}
+
+pub fn create_runtime(with_debug: bool) -> LuaRuntime {
     let runtime = if with_debug {
         unsafe { Lua::new_with_debug() }
     } else {
@@ -9,5 +37,5 @@ pub fn create_runtime(with_debug: bool) -> Lua {
 
     // Customise runtime here
 
-    runtime
+    LuaRuntime(runtime)
 }
\ No newline at end of file
diff --git a/src/server/mod.rs b/src/server/mod.rs
index 6fc18512e77ab17aca44b8d249c5bc14be02073e..21e4c644b65d3427cece43ac3b17f6d003db0769 100644
--- a/src/server/mod.rs
+++ b/src/server/mod.rs
@@ -2,4 +2,4 @@ mod server;
 mod lua;
 
 pub use self::server::create_server;
-pub use self::lua::create_runtime;
\ No newline at end of file
+pub use self::lua::{LuaRuntime, create_runtime};
\ No newline at end of file
diff --git a/src/server/server.rs b/src/server/server.rs
index 5cdcd85d98e1a3d2564bdc1c0bfee292602805be..37a1b9453d9ddb28ee397b4b369509eb4c239f63 100644
--- a/src/server/server.rs
+++ b/src/server/server.rs
@@ -1,7 +1,6 @@
 use rocket::{self, Rocket, Config};
 use cli::{Args, SwerveConfig};
 use routing;
-use server;
 
 pub fn create_server(args: Args, config: SwerveConfig) -> Rocket {
 	let server_config = server_config_from_input(args.clone(), config.clone());
@@ -37,9 +36,6 @@ pub fn create_server(args: Args, config: SwerveConfig) -> Rocket {
 		}));
 	}
 
-    let lua_runtime = server::create_runtime(false);
-    server = server.manage(lua_runtime);
-
 	server
 }