Node.js | Go
A Tale of Two Worlds
About me
Language
Usability
Standards
Ecosystem
JavaScript/ Node.js | Go | |
---|---|---|
OOP? |
Prototypical inheritance | Structs, methods and interfaces |
Functional? | ||
Type System | Dynamic, weak | Static, strong, some short-cuts |
Memory Mgmt. | ||
Execution | Just-In-Time at runtime | Compiled to binary |
Concurrency | Single threaded event loop | Goroutines (light-weight threads) |
Functions as "first-class objects", closures, ...
Garbage Collection
Source: https://xkcd.com/303/
Concurrency
Like, perhaps we could forget about threads entirely [...]
But within a single process, we could handle many, many requests by being completely asynchronous.I believe strongly in this idea at the time, but over the past couple of years, I think that’s probably not the end-all and be-all idea for programming. In particular, when Go came out.
[...] the interface that they present to the user is blocking,
and I think that that’s a nicer programming model.
- Ryan Dahl, Creator of Node.js
Source: https://www.mappingthejourney.com/single-post/2017/08/31/episode-8-interview-with-ryan-dahl-creator-of-nodejs/
Concurrency in Node.js
// Callback
request('http://example.com', function (err, res, body) {
console.log(err, body);
});
// Promise
request({uri: 'http://example.com', json: true})
.then(function (body) {
console.log(body);
})
.catch(function (err) {
console.log(err);
});
// Async/Await
async func fetchExample() {
try {
const response = await fetch('http://example.com');
const body = await response.json();
console.log(body);
} catch (err) {
console.log(err);
}
};
fetchExample();
Asynchronous code ...
... but single-threaded event loop
Concurrency in Go
res, err := http.Get("http://example.com")
if err != nil {
fmt.Println(err)
} else {
// ...
}
Synchronous/blocking code ...
... but mostly inside Goroutines
// Excerpt from net/http/server.go
func (srv *Server) Serve(l net.Listener) error {
// ...
for {
rw, e := l.Accept()
// ...
c := srv.newConn(rw)
c.setState(c.rwc, StateNew)
go c.serve(ctx)
}
}
Language
Usability
Standards
Ecosystem
Usability for APIs - Server Setup
const express = require('express')
const app = express()
function customAuth(req, res, next) {
// ...
next()
}
app.use(customAuth)
app.put('/users/:id', (req, res) => {
// ...
})
app.listen(3000)
package main
import (
"net/http"
"github.com/labstack/echo"
)
func CustomAuth(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
// ...
return next(c)
}
}
func main() {
e := echo.New()
e.Use(CustomAuth)
e.PUT("/users/:id", func(c echo.Context) error {
// ...
})
e.Start(":3000")
}
Performance
Source: www.techempower.com/benchmarks/#section=data-r16&hw=cl&test=json
* DB query value not restify but plain node.js
Usability for APIs - Parsing JSON
// JSON response from some other service
"{\"name\": \"Kathryn Janeway\",\"age\": 30,\"isAdmin\": true,\"birthday\": \"2344-05-20\"}"
user = JSON.parse(res.body);
console.log(user);
type User struct {
Name string `json:"name"`
Age int64 `json:"age"`
IsAdmin bool `json:"isAdmin"`
Birthday string `json:"birthday"`
}
user := User{}
json.NewDecoder(res.Body).Decode(&user)
fmt.Println(user)
Usability for APIs - Sending Requests
const options = {
method: 'POST',
uri: 'http://example.com',
headers: {
'Authorization': 'Bearer QWxhabc'
},
body: {foo: 'bar'},
json: true
}
request(options, function (err, res, body) {
console.log(err, res.statusCode, body)
})
?
Language
Usability
Standards
Ecosystem
Community
"Dictatorship"
TC39 for JavaScript
TCS for Node.js
Go Team at Google
(Russ Cox)
Governance
Go's Orthogonal Feature Set
type Rectangle struct {
Height int
Width int
}
func (r Rectangle) CalcArea() int {
return r.Height * r.Width
}
type Shape interface {
CalcArea() int
}
Data (Struct)
Functionality (Method)
Abstraction (Interface)
Unique, simple, independent concepts
that play well together
a platfrom created by Katrina Owen @kytrinyx
exercism.io/submissions/af62110dc0d44465bc68769cfa359b9d
exercism.io/submissions/bf51ddffb3ed49639e4f6f70bc13b0a9
exercism.io/submissions/e1307ba076a849769b15b0625a3d5c3d
exercism.io/submissions/21416c0b09564fd19a55a59272c2db7e
exercism.io/submissions/ec4cc44d61854d61a25a90ab427a802b
exercism.io/submissions/c9a592e400da4011b61350cc05c19f72
Go has lots of Rules/Guidelines
Starting with the compiler...
... through to guidelines
invalid operation: a + b (mismatched
types int and int64)
cannot use m (type MyType) as type
Stringer in assignment: MyType does not
implement Stringer (String method has
pointer receiver)
myVar declared and not used
imported and not used: "time"
golang.org/doc/effective_go.html golang.org/doc/faq github.com/golang/go/wiki blog.golang.org
- "packages are given lower case, single-word names"
- "Error strings should not start with a capital letter"
- "The first sentence [of a doc comment] should be a one-sentence summary that starts with the name being declared."
- Test data belongs in a folder called "testdata"
- ...
fewer features
more rules/ guidelines
less diversity in the code
fewer discussions
more time/energy for the actual work
Node.js Supplementary Material?
nodejs.org/en/docs/guides
Tooling in Go - "Batteries included"
Formatting | gofmt, goimports |
Linting | go vet, golint |
Tests | go test, go cover |
Documentation | godoc |
Performance Analysis | pprof |
... | ... |
Language
Usability
Standards
Ecosystem
Source: www.modulecounts.com
Discovery for Node.js Modules
Discovery for Go Packages
Dependency Management
1995
Birth of
JavaScript
2009
Birth of
Node.js
2018
2012
2009
Birth of
Go
2018
2016
VGO
What
to
use
?
... if speed of development is the most important thing
... if it should be hard to do something wrong
Node.js and Go public
By junedev
Node.js and Go public
- 1,834