Last class, we made an RPC framework by ourselves. In this class, we will take on a slightly more difficult task of manually making a Web framework. I don’t like to call it an MVC framework because I didn’t think of it as an MVC when I made this little project. It was all about ease of use.

First, how easy is this Web framework to use

Hello World

import httpkids.server.KidsRequestDispatcher;
import httpkids.server.Router;
import httpkids.server.internal.HttpServer;

public class HelloWorld {

    public static void main(String[] args) {
        var rd = new KidsRequestDispatcher("/kids".new Router((ctx, req) -> {
            ctx.html("Hello, World");
        }));
        new HttpServer("localhost".8080.2.16, rd).start();
    }

}

http://localhost:8080/kids
Copy the code

KidsRequestDispatcher is a request dispatcher that throws the received HTTP request object to the responding RequestHandler for processing. The Router is used to build the route and is responsible for hooking up the URL rules with the RequestHandler to form a complex mapping table.

In order to simplify the implementation details, the Router does not support complex URL rules, such as RESTFUL formats that write parameters inside urls.

HttpServer is the core object of the Web server. In addition to the IP port, the HttpServer needs to provide three key parameters, namely, the number of I/O threads, the number of service threads and the request dispatker object. IO threads handle word reads and writes and are managed internally by Netty. Business threads are dedicated to handling HTTP requests and are managed by the HTTPKids framework.

A comprehensive example

import java.util.HashMap;

import httpkids.server.KidsRequestDispatcher;
import httpkids.server.Router;
import httpkids.server.internal.HttpServer;

public class HelloWorld {

	public static void main(String[] args) {
		var router = new Router((ctx, req) -> {
			ctx.html("Hello, World");  // Plain text HTML
		})
		.handler("/hello.json", (ctx, req) -> {
			ctx.json(new String[] { "Hello"."World" });  // JSON API
		})
		.handler("/hello", (ctx, req) -> {
			var res = new HashMap<String, Object>();
			res.put("req", req);
			ctx.render("playground.ftl", res); // Template rendering
		})
		.handler("/world", (ctx, req) -> {
			ctx.redirect("/hello");  / / 302 jump
		})
		.handler("/error", (ctx, req) -> {
			ctx.abort(500."wtf");  / / exception
		})
		.resource("/pub"."/static")  // Static resources
		.child("/user", () - > {// Route nesting
			return new Router((ctx, req) -> {
				ctx.html("Hello, World");
			})
			.handler("/hello.json", (ctx, req) -> {
				ctx.json(new String[] { "Hello"."World" });
			})
			.filter((ctx, req, before) -> {  // filters, interceptors
				if (before) {
					System.out.printf("before %s\n", req.path());
				} else {
					System.out.printf("after %s\n", req.path());
				}
				return true;
			});
		});

		var rd = new KidsRequestDispatcher("/kids", router); // Request the dispatcher
		rd.templateRoot("/tpl"); // The template classpath root directory
		rd.exception(500, (ctx, e) -> { // Exception handling
			ctx.html("what the fuck it is".500);
		})
		.exception((ctx, e) -> {  // General exception handling
			ctx.html("mother fucker!", e.getStatus().code());
		});

		var server = new HttpServer("localhost".8080.2.16, rd);
		server.start();
		
		Runtime.getRuntime().addShutdownHook(new Thread() {

			public void run(a) {
				server.stop(); // Stop gracefully}}); } } http://localhost:8080/kids
http://localhost:8080/kids/hello
http://localhost:8080/kids/hello.json
http://localhost:8080/kids/world
http://localhost:8080/kids/error
http://localhost:8080/kids/pub/bootstrap.min.css
http://localhost:8080/kids/user
http://localhost:8080/kids/user/hello
Copy the code

The stack depth

Non-java programmers often complain about the complexity of Java’s framework, especially its horrible call stack. For example, this picture is widely circulated.

So here I’m going to highlight the HttpKids call stack and let’s see how deep it really is

Project code

HttpKids Web Framework based on Netty for Kids of You

RpcKids RPC Framework based on Netty for Kids of You

The big bang

Code hole