Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Abdulazeez Abdulazeez
Abdulazeez Abdulazeez

Posted on

     

Introducing Polka: A micro web server.

polka

What is Polka ?

Polka is an extremely minimal, highly performant Express.js alternative.

Installation.

npm i --save polka
Enter fullscreen modeExit fullscreen mode

Usage

Polka has similar patterns with ExpressJS in terms of routing and API calls.

Simple Example.

constpolka=require('polka');polka().get('/',(req,res)=>{res.end('Hello there !');}).listen(9000).then(_=>{console.log(`> Running on localhost:3000`);});
Enter fullscreen modeExit fullscreen mode

Polka's API

Polka has four (4) main API methods.

  • Polka(options) - Returns an instance of polka.
  • use(base, ..fn)
  • parse(req)
  • listen(port, hostname)
  • handler(req, res, parsed)

Routing with Polka.

Routes are used to define how an application responds to varying HTTP methods and endpoints.

Basics

Each route is comprised of apath pattern, aHTTP method, and ahandler (aka, what you want to do).

In code, this looks like:

app.METHOD(pattern,handler);
Enter fullscreen modeExit fullscreen mode

wherein:

  • app is an instance ofpolka*method is any valid HTTP method, lowercased
  • pattern is a routing pattern (string)
  • handler is the function to execute whenpattern is matched

Also, a single pathname (orpattern) may be reused with multiple METHODs.

The following example demonstrates some simple routes.

constapp=polka();app.get('/',(req,res)=>{res.end('Hello world!');});app.get('/users',(req,res)=>{res.end('Get all users!');});app.post('/users',(req,res)=>{res.end('Create a new User!');});app.put('/users/:id',(req,res)=>{res.end(`Update User with ID of${req.params.id}`);});app.delete('/users/:id',(req,res)=>{res.end(`CY@ User${req.params.id}!`);});
Enter fullscreen modeExit fullscreen mode

Patterns

Unlike the very popularpath-to-regexp, Polka uses string comparison to locate route matches. Whilefaster & more memory efficient, this does also prevent complex pattern matching.

However, have no fear! 💥 All the basic and most commonly used patterns are supported. You probably only ever used these patterns in the first place. 😉

Seecomparison for the list ofRegExp-based patterns that Polka does not support.

The supported pattern types are:

  • static (/users)
  • named parameters (/users/:id)
  • nested parameters (/users/:id/books/:title)
  • optional parameters (/users/:id?/books/:title?)
  • any match / wildcards (/users/*)

Parameters

Any named parameters included within your routepattern will be automatically added to your incomingreq object. All parameters will be found withinreq.params under the same name they were given.

Important: Your parameter names should be unique, as shared names will overwrite each other!

app.get('/users/:id/books/:title',(req,res)=>{let{id,title}=req.params;res.end(`User:${id} && Book:${title}`);});
Enter fullscreen modeExit fullscreen mode
$curl /users/123/books/Narnia#=> User: 123 && Book: Narnia
Enter fullscreen modeExit fullscreen mode

Methods

Any valid HTTP method is supported! However, only the most common methods are used throughout this documentation for demo purposes.

Note: For a full list of valid METHODs, please seethis list.

Handlers

Request handlers accept the incomingClientRequest and the formulatingServerResponse.

Every route definition must contain a validhandler function, or else an error will be thrown at runtime.

Important: You mustalways terminate aServerResponse!

It's avery good practice toalways terminate your response (res.end) inside a handler, even if you expect a middleware to do it for you. In the event a response is/was not terminated, the server will hang & eventually exit with aTIMEOUT error.

Note: This is a nativehttp behavior.

Async Handlers

If using Node 7.4 or later, you may leverage nativeasync andawait syntax! 😻

No special preparation is needed — simply add the appropriate keywords.

constapp=polka();constsleep=ms=>newPromise(r=>setTimeout(r,ms));asyncfunctionauthenticate(req,res,next){lettoken=req.getHeader('authorization');if(!token)returnapp.send(res,401);req.user=awaitUsers.find(token);// <== fakenext();// done, woot!}app.use(authenticate).get('/',async(req,res)=>{// log middleware's findingsconsole.log('~> current user',req.user);// force sleep, because we can~!awaitsleep(500);// send greetingres.end(`Hello,${req.user.name}`);});
Enter fullscreen modeExit fullscreen mode

Middleware

Middleware are functions that run in between (hence "middle") receiving the request & executing your route'shandler response.

Coming from Express? Use any middleware you already know & love! 🎉

The middleware signature receives the request (req), the response (res), and a callback (next).

These can apply mutations to thereq andres objects, and unlike Express, have access toreq.params,req.pathname,req.search, andreq.query!

Most importantly, a middlewaremust either callnext() or terminate the response (res.end). Failure to do this will result in a never-ending response, which will eventually crash thehttp.Server.

// Log every requestfunctionlogger(req,res,next){console.log(`~> Received${req.method} on${req.url}`);next();// move on}functionauthorize(req,res,next){// mutate req; available laterreq.token=req.getHeader('authorization');req.token?next():((res.statusCode=401)&&res.end('No token!'));}polka().use(logger,authorize).get('*',(req,res)=>{console.log(`~> user token:${req.token}`);res.end('Hello, valid user');});
Enter fullscreen modeExit fullscreen mode
$curl /# ~> Received GET on /#=> (401) No token!$curl-H"authorization: secret" /foobar# ~> Received GET on /foobar# ~> user token: secret#=> (200) Hello, valid user
Enter fullscreen modeExit fullscreen mode

In Polka, middleware functions are mounted globally, which means that they'll run on every request. Instead, you'll have to apply internal filters to determine when & where your middleware should run.

Note: This might change in Polka 1.0 🤔

functionfoobar(req,res,next){if(req.pathname.startsWith('/users')){// do something magical}next();}
Enter fullscreen modeExit fullscreen mode

Middleware Errors

If an error arises within a middleware, the loop will be exited. This means that no other middleware will execute & neither will the route handler.

Similarly, regardless ofstatusCode, an early response termination will also exit the loop & prevent the route handler from running.

There are three ways to "throw" an error from within a middleware function.

Hint: None of them usethrow

  1. *Pass any string tonext() *

    This will exit the loop & send a500 status code, with your error string as the response body.

polka().use((req,res,next)=>next('💩')).get('*',(req,res)=>res.end('wont run'));
Enter fullscreen modeExit fullscreen mode
$curl /#=> (500)
Enter fullscreen modeExit fullscreen mode
  1. Pass anError tonext()

    This is similar to the above option, but gives you a window in changing thestatusCode to something other than the500 default.

functionoopsies(req,res,next){leterr=newError('Try again');err.code=422;next(err);}
Enter fullscreen modeExit fullscreen mode
$curl /#=> (422) Try again
Enter fullscreen modeExit fullscreen mode
  1. Terminate the response early

    Once the response has been ended, there's no reason to continue the loop!

    This approach is the most versatile as it allows to control every aspect of the outgoingres .

functionoopsies(req,res,next){if(true){// something bad happened~res.writeHead(400,{'Content-Type':'application/json','X-Error-Code':'Please dont do this IRL'});letjson=JSON.stringify({error:'Missing CSRF token'});res.end(json);}else{next();// never called FYI}}
Enter fullscreen modeExit fullscreen mode
$curl /#=> (400) {"error":"Missing CSRF token"}
Enter fullscreen modeExit fullscreen mode

Benchmarks

A round of Polka-vs-Express benchmarks across varying Node versions can befound here.

Important: Time is mostly spent inyour application code rather than Express or Polka code! Switching from Express to Polka will (likely) not show such drastic performance gains.

Node 8.9.0Native    Thread Stats   Avg      Stdev     Max   +/- Stdev        Latency     2.24ms  112.34us   5.57ms   92.15%        Req/Sec     5.38k    99.48     5.57k    81.81%      432562 requests in 10.10s, 42.90MB read    Requests/sec:  42815.14    Transfer/sec:      4.25MBPolka    Thread Stats   Avg      Stdev     Max   +/- Stdev        Latency     2.26ms  115.55us   5.19ms   87.16%        Req/Sec     5.32k    97.34     5.55k    72.77%      428208 requests in 10.10s, 42.47MB read    Requests/sec:  42388.92    Transfer/sec:      4.20MBExpress    Thread Stats   Avg      Stdev     Max   +/- Stdev        Latency     5.15ms  421.69us   8.51ms   77.95%        Req/Sec     2.34k    77.06     2.55k    72.12%      186390 requests in 10.01s, 36.97MB read    Requests/sec:  18628.36    Transfer/sec:      3.70MBFastify    Thread Stats   Avg      Stdev     Max   +/- Stdev        Latency     2.91ms  201.13us   7.51ms   58.07%        Req/Sec     4.14k   130.04     4.48k    65.59%      333158 requests in 10.10s, 41.30MB read    Requests/sec:  32979.84    Transfer/sec:      4.09MBKoa    Thread Stats   Avg      Stdev     Max   +/- Stdev        Latency     3.43ms  369.96us   8.67ms   87.30%        Req/Sec     3.51k   114.78     4.12k    69.76%      281808 requests in 10.10s, 38.97MB read    Requests/sec:  27892.99    Transfer/sec:      3.86MB
Enter fullscreen modeExit fullscreen mode

Comparisons

Polka's API aims to bevery similar to Express since most Node.js developers are already familiar with it. If you know Express, you already know Polka! 💃

There are, however, a few main differences. Polka does not support or offer:

1)Any built-in view/rendering engines.
Most templating engines can be incorporated into middleware functions or used directly within a route handler.

2)The ability tothrow from within middleware.
However, all other forms of middleware-errors are supported.( see middleware options)

functionmiddleware(res,res,next){// pass an error message to next()next('uh oh');// pass an Error to next()next(newError('🙀'));// send an early, customized error responseres.statusCode=401;res.end('Who are you?');}
Enter fullscreen modeExit fullscreen mode

3)Express-like response helpers... yet! (#14)
Express has a nice set ofresponse helpers. While Polka relies on thenative Node.js response methods, it would be very easy/possible to attach a global middleware that contained a similar set of helpers. (TODO)

4)RegExp-based route patterns.
Polka's router uses string comparison to match paths against patterns. It's a lot quicker & more efficient.
The following routing patternsare not supported:

app.get('/ab?cd',_=>{});app.get('/ab+cd',_=>{});app.get('/ab*cd',_=>{});app.get('/ab(cd)?e',_=>{});app.get(/a/,_=>{});app.get(/.*fly$/,_=>{});
Enter fullscreen modeExit fullscreen mode

The following routing patternsare supported:

app.get('/users',_=>{});app.get('/users/:id',_=>{});app.get('/users/:id?',_=>{});app.get('/users/:id/books/:title',_=>{});app.get('/users/*',_=>{});
Enter fullscreen modeExit fullscreen mode

Credits.

All credits goes toLuke Edwards for his awesome works.

Top comments(4)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
itsjzt profile image
Saurabh Sharma
Fullstack Web developer.
  • Location
    Delhi, India
  • Work
    Fullstack Web Developer at Codeword Tech
  • Joined

However, have no fear! 💥

  • were you trying emojis like in GitHub
CollapseExpand
 
taffit profile image
taffit
  • Joined

Seems to me like a 1:1-copy of the Readme of the repository, therefore also the emojis like in GitHub.

CollapseExpand
 
kvng_zeez profile image
Abdulazeez Abdulazeez
Software engineer, author and technical writer.
  • Joined

Oh Yeah ! Silly me

CollapseExpand
 
systemx profile image
Mohammed Fellak
Software Engineer, UI/UX Designer
  • Location
    Tampa, Florida, US
  • Education
    CS50 Web
  • Work
    Software Engineer, UI/UX Designer at Ashley Furniture
  • Joined

Great! Thanks

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Software engineer, author and technical writer.
  • Joined

More fromAbdulazeez Abdulazeez

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp