这是我第四篇第六届青训营文章,同时我发布到外网:open.substack.com/pub/minyizo…
Concept of HTTP
The Hypertext Transfer Protocol (HTTP) is an application layer protocol in the Internet protocol suite model for distributed, collaborative, hypermedia information systems. (wiki)
Methods
The methods GET, HEAD, and POST are defined as cacheable. In contrast, the methods PUT, DELETE, CONNECT, OPTIONS, TRACE, and PATCH are not cacheable.
Status Code
1XX (informational): The request was received, continuing process.
2XX (successful): The request was successfully received, understood, and accepted.
3XX (redirection): Further action needs to be taken in order to complete the request.
4XX (client error): The request contains bad syntax or cannot be fulfilled.
5XX (server error): The server failed to fulfill an apparently valid request.
Http framework design
Http framework with aforementioned design will be more clear.
Middleware Design
onion model
A good example is KOA:
We register middleware using the app.use method. Multiple middlewares can be registered, and their execution order depends on the order of registration; the ones registered earlier are executed first.
Middleware is simply a function that accepts two parameters provided by Koa:
ctx: The context object.next: The next function.
The ctx object contains various parameters, such as the request object (request) and the response object (response).
Calling the next function will execute the next middleware in the chain. If you don't call the next function, the next middleware will not be executed.
const Koa = require('koa');
const app = new Koa();
// Middleware 1
app.use(async (ctx, next) => {
console.log('Middleware 1');
await next();
console.log('Complete');
})
// Middleware 2
app.use(async (ctx, next) => {
console.log('Middleware 2')
const data = await getData();
ctx.body = { data };
})
// Simulate getting data from a database
const getData = async () => {
return 'Hello World!';
}
app.listen(3000);
- Execute the code before
next(). - Then, execute all the code of the middleware 2 that comes after
next(). - Finally, execute the code after
next().
Therefore, the log looks like this:
Middleware 1
Middleware 2
Complete
Follow up:
If user doesn’t call next manually, we still can set a limit for index and stop it:
Route Design
Using a prefix tree (also known as a trie) can make querying more convenient. ( You can find out some questions in leetcode about tire. LOL.)
Data structure will be like:
| map | method | trie | node |
Meanwhile, you can use a list to record handlers chain
Codec Design
Contexts should not be stored inside a struct type, but instead passed to each function that needs it. This article expands on that advice with reasons and examples describing why it's important to pass Context rather than store it in another type: go.dev/blog/contex…
Transport Design
BIO uses a one-to-one mapping between threads and connections, while NIO uses a one-to-many mapping, allowing for more efficient handling of I/O operations with fewer threads.
BIO: go net, manage buffer by users
NIO: netpoll is a good example - github.com/cloudwego/n…