Reputation: 21
I'm trying to make a simple HTTP module, similar to express, to help learn how to use HTTP.
When working with express I often use parameters such as:
app.get('/id/:id' (req, res) => {console.log(req.params.id); stuff})
I was wondering-
Upvotes: 2
Views: 1129
Reputation: 114014
Yes but you need to process it manually.
Assuming you're using node's http module, the information you are looking for is in req.url
but it includes the whole url path.
For example, you want to parse /id/:id
, and the browser is making a request to http://your.server/id/100?something=something
. Then the value of req.url
will be:
/id/100?something=something
But if you are writing an HTTP module from scratch using the net module then you need to know the format of an HTTP request. Basically an HTTP request looks like a text file with the following format:
GET /id/100?something=something HTTP/1.1
Host: your.server
The header section ends with double newlines. Technically it should be \r\n\r\n
but \n\n
is also acceptable. You first need to get the url from the first line of the request between the protocol (GET in the example above but can be POST, PUT etc.) and the HTTP version number.
For anyone interested in writing a HTTP server from scratch I always recommend James Marshall's excellent article: https://www.jmarshall.com/easy/http/. It was originally written in the late 90s but to this day I haven't found a clearer summary of the HTTP protocol. I've used it myself to write my first HTTP server.
Now you have to write code to extract the 100
from the string.
If you are doing this manually, not trying to write a framework like Express, you can do it like this:
const matches = req.url.match(/id\/([^\/?]+)/);
const id = matches[1];
If you want to write a library to interpret the /id/:id
pattern you can maybe do something like this (note: not an optimized implementation, also it behaves slightly differently to express):
function matchRoute (req, route) {
const [ urlpath, query ] = req.url.split('?'); // separate path and query
const pathParts = urlpath.split('/');
const routeParts = urlpath.split('/');
let params = {};
for (let i=0; i<pathParts.length; i++) {
if (routeParts[i].match(/^:/)) { // if route part starts with ":"
// this is a parameter:
params[routeParts[i].replace(':','')] = pathParts[i];
}
else {
if (routeParts[i] !== urlParts[i]) {
return false; // false means path does not match route
}
}
// if we get here (don't return early) it means
// the route matches the path, copy all found params to req.params:
req.params = params;
return true; // true signifies a match so we should process this route
}
}
// Test:
let req.url = '/id/100';
let result = matchRoute(req, '/id/:id');
console.log(result, req.params); // should print "true, {id:100}"
Upvotes: 1
Reputation: 1925
Your question is a little bit confusing but I think what you mean is how to implement an HTTP Router in pure javascript instead of relying on a framework like express.
If that's the case I support your initiative 100%! It's really important to understand what is going on behind the scenes.
A good way to really understand a good way to do so would be by reading the source code of a good router that is already out there.
You could study the Express router's source code but I recommend you to go play with find-my-way which is a dedicated router that you can use with HTTP only without any other framework.
Upvotes: 1