Search code examples
javaroutesfront-controller

Implementing Controller and Routes in Java


I'm implementing a webapplication which uses a Router to validate the incoming request and map it to an action in a controller.

The routes are defined in a file like this:

"/users/all","UserController.all"
"/users/user_id","UserController.get"
"/posts/add","PostController.add"
"/posts/post_id","PostContoller.get"

The Routes class is as follows:

public class Routes {

    HashMap<String,String> routes;

    public Routes() {
        this.routes = new HashMap<String,String>();
        readRoutes();
    }

    public HttpResponse route(HttpRequest request) {
        String mapper[] = routes.get(request.getUri()).split(".");
        try {
            return (HttpResponse) Class.forName(mapper[0]).getMethod(mapper[1],HttpRequest.class).invoke(null, request);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    private void readRoutes() {
        // Reads the routes file and loads the routes hash map

    }
}

I currently have two controllers, User and Post as follows:

public class UserController {

    public static Collection<String> all(HttpRequest request) {
        return DB.Users.all();
    }

    public static String get(HttpRequest request) {
        // Extract id from request
        return DB.Users.get(id);
    }
}

public class PostController {

    public static void add(HttpRequest request) {
        // Get the data from the request and do the processing
        return DB.Posts.add(data);
    }

    public static String get(HttpRequest request) {
        // Extract id from request
        return DB.Posts.get(id);
    }
}

The above example is just to give an idea of what I'm trying to achieve. The obvious checks on any exceptions have been ignored.

My question is: The routes class converts the value(String) in the routes hash map to a Method in the Controller and invokes it. Is this an effecient way? I read that invoking a Method in this manner is a bad way of coding and should be avoided, but I'm not sure how else to implement this. Routes does this mapping every time a request is matched, would this slow down the application?

Any suggestions or examples on how to do this in an effecient way would be very helpful.

I know there are a bunch of MVC frameworks which I can use, but I'd really like to clarify the above.


Solution

  • Pre-compute or cache this information as it is known before hand:

    Class.forName(mapper[0]).getMethod(mapper[1], HttpRequest.class)
    

    So

    this.routes = new HashMap<String, Method>()
    

    leads to

    routes.get(request.getUri()).invoke(null, request)
    

    It would make you implementation faster.

    Other than that it is a sound approach.