NEXTSCRIBE

Posts tagged with "api"

Gofiber vs Echo for Building APIs in Go

Two Go web frameworks walk into a bar... who wins?

Here’s a list of 10 things I noticed while messing around with both Gofiber and Echo.

Spoiler alert they both good but also not the same vibe.


1. Speed and perf

Gofiber is freakin fast.
Like it’s built on top of fasthttp which is optimized like crazy. You’ll see better latency numbers if you’re into benchmarking stuff.
Echo’s fast too but not Gofiber fast. It’s using the standard net/http under the hood so yknow it’s more traditional.


2. Ease of use

Echo just feels comfy.
The APIs are super clear and not doing anything too weird. You can just sit down and write a REST API without googling too much.
Gofiber can feel a bit different if you’re used to standard Go http.


3. Middleware support

Both support middlewares.
But Echo got a richer ecosystem out the box.
Like you need JWT auth logging rate limiting whatever... Echo prob has a plug for that.
Gofiber has some too but it’s a bit more scattered and sometimes you end up writing your own stuff.


4. Request context

Echo uses Go’s standard context.Context which is great cause it’s what everything else in Go uses.
Gofiber has its own context thing which can be kinda annoying if you tryna pass values around or plug into something like gorm or whatever.


5. Routing

Both support route groups and params and all that jazz.
Gofiber routes are a bit more expressive I’d say. Like you can chain stuff nicely.
Echo’s routing is super solid though and very readable.


6. Error handling

Echo has a solid error handling system.
You can define custom error handlers and respond consistently.
Gofiber has it too but again feels a bit more manual sometimes.


7. Community and docs

Echo been around longer.
So more blog posts stackoverflow answers and all that.
Gofiber docs are nice too but community support is still catching up a bit.


8. Websocket support

Both have it.
Gofiber’s based on fasthttp so it does fine... but you need to be careful cause fasthttp doesn’t support full standard http features.
Echo works with Gorilla Websockets or whatever you like.


9. Deployment

No big diff here.
They both compile to a single binary and work great in Docker or whatever you use.
But since Gofiber is a bit faster you might get better resource usage in high traffic stuff.


10. Learning curve

Echo is just easier to grok if you already wrote stuff with net/http before.
Gofiber kinda does its own thing and takes a sec to get used to.


Bonus Point. Syntax Vibes

Some folks just like how code looks and feels.
Here’s a simple example of a basic API route in both to compare.

Gofiber

package main import "github.com/gofiber/fiber/v2" func main() { app := fiber.New() app.Get("/hello", func(c *fiber.Ctx) error { return c.SendString("Hello from Fiber") }) app.Listen(":3000") }

Echo

package main import ( "net/http" "github.com/labstack/echo/v4" ) func main() { e := echo.New() e.GET("/hello", func(c echo.Context) error { return c.String(http.StatusOK, "Hello from Echo") }) e.Start(":3000") }

Echo code feels more Go-ish.
Gofiber code feels snappy and clean but kinda not standard if you’re picky about that.


So which one should you use?

Gofiber
Use it if you care a lot about speed or building high perf microservices and you're ok with its custom style.

Echo
Use it if you want a super stable well documented easy to maintain API in pure Go style.

Honestly try both for a bit and see what feels better.
Your future self will thank you. Trust me.


That’s it.
Hope that helps.

Feel free to ping me if you wanna nerd out more on Go stuff.

Node vs Go for building APIs – No fluff, just real dev talk

Had this convo with a friend the other day. We were talking backend stuff and it came up, should you build your API in Node or in Go? Happens all the time. They both work, but they feel real different when you are the one doing the building.

So if you are stuck choosing or just trying to get the vibe of each, here is a straight up comparison. No marketing lingo, no sales pitch. Just how it really goes when you are building stuff.

Here are ten things that matter when you are picking between Node and Go for API work.

1. Getting started

Node
Quick to get going. Run a command, install express, write a few lines and boom you got an API. Great for hacking stuff together fast.

Go
Takes a little more setup. You make folders, write more code up front, think a bit about structure. Not hard, just slower to boot.

Verdict
Node wins here for speed. Go feels more clean but slower to kick off.

2. Concurrency and speed

Go
Built for handling a ton of stuff at once. Goroutines let you run functions side by side with almost no cost. You can handle a lot of traffic.

Node
Uses one thread with async calls. Works great for input and output stuff, but if you throw CPU work at it, things can get rough.

Verdict
Go takes this one for raw performance and traffic handling.

3. Typing

Node
JavaScript has no types. You can use TypeScript to get types, but that is an extra step.

Go
Always typed. You get errors before you run stuff. Helps a lot when your app grows.

Verdict
Go if you like your code to stay stable. Node if you want to move fast and maybe fix stuff later.

4. Error handling

Go
You will write a lot of if err is not nil. It is a little annoying but very clear. You always handle stuff up front.

Node
Use try and catch, or async and await. Feels nicer, but it is easy to forget things if you are not paying attention.

Verdict
Go is safer but wordy. Node is smooth but needs discipline.

5. Tools and setup

Go
Comes with what you need. Formatter, build tool, testing, it is all built in.

Node
You choose your own tools. Linter, formatter, test runner, all separate things. You spend time setting stuff up.

Verdict
Go keeps it simple. Node gives you more choice but more work too.

6. Libraries and packages

Node
The package world is huge. You want something? It probably exists. But you might have five versions of it and not know which one to trust.

Go
Fewer packages but usually solid. The quality is better on average but you will have less to pick from.

Verdict
Node for more options. Go for more stability.

7. Deployment

Go
Compile your app and you get one file. That is it. Upload it anywhere and it just works.

Node
Needs Node installed, maybe a process manager like PM2 or run it in a container. More moving parts.

Verdict
Go makes deployment easy. Node takes more steps.

8. Community

Node
Feels casual. A lot of frontend folks using it for backend now. Tons of help online.

Go
Feels more serious. Devops and backend engineers mostly. Still helpful, just a different energy.

Verdict
Node for a relaxed vibe. Go for focused and clean.

9. Scaling

Go
Made to scale. Light memory use, fast, good at handling many requests at once.

Node
Can scale, but needs more planning. You might need clusters or extra tools if traffic gets big.

Verdict
Go is better out of the box for scale.

10. Writing code

Node
Feels fast to write. Async and await make it readable. If you know JavaScript, you will be comfy right away.

Go
More rules, fewer surprises. At first it feels strict, but after a while you stop thinking about weird bugs.

Verdict
Node is flexible. Go is solid. Just depends on your style.


Quick code time, same API in both

Node using Express

const express = require('express') const app = express() app.get('/hello', (req, res) => { res.send('Hello from Node!') }) app.listen(3000, () => { console.log('Server running at http://localhost:3000') })

Go using standard library

package main import ( "fmt" "net/http" ) func helloHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello from Go!") } func main() { http.HandleFunc("/hello", helloHandler) fmt.Println("Server running at http://localhost:3000") http.ListenAndServe(":3000", nil) }

So which one should you use

If you want to build fast, love JavaScript, and want a lot of tools at your fingertips, go with Node.

If you care about performance, want easy deployment, and do not mind being a little more strict, Go is a great choice.

No bad answer here. Just pick what fits you and your project.

Now go write some code.

Express vs Fastify: Which Node.js Framework Should You Actually Use?

Alright, so you’re building an API with Node.js and you're thinking, "Do I just go with Express like everyone else, or should I try out Fastify and see what the hype is about?"

Let’s break it down. I’ve used both, and they both work. But depending on your project, one might make your life way easier than the other.

Express

Express is the old reliable. It’s been around forever, and pretty much every Node developer has used it at some point. If you're looking for something stable with a massive ecosystem, Express is still a solid choice.

Pros

  • Huge community. If you run into an issue, someone on Stack Overflow already solved it five years ago.
  • Tons of middleware. You need something? There’s probably a package for it.
  • Very flexible. It doesn’t force structure or conventions on you.

Cons

  • Not the fastest, performance wise.
  • Some parts feel a little dated if you’re used to more modern frameworks.
  • Lacks builtin support for things like input validation or automatic API docs.

Express example

// express-server.js const express = require('express'); const app = express(); app.use(express.json()); app.get('/', (req, res) => { res.send('Hello from Express'); }); app.listen(3000, () => { console.log('Express app running on http://localhost:3000'); });

Easy to understand, works everywhere, no surprises.

Fastify

Fastify is newer, but it's built for performance. If you're starting something fresh and want the benefits of modern architecture, Fastify's got you covered. It's fast, lightweight, and actually pretty nice to work with once you get the hang of it.

Pros

  • Way faster than Express in most benchmarks.
  • Builtin schema validation using JSON Schema.
  • First class TypeScript support.
  • Automatic Swagger docs if you want them.

Cons

  • Smaller ecosystem. Not every Express middleware has a Fastify version.
  • A bit of a learning curve if you're used to Express's "do whatever you want" style.
  • Some plugins are still catching up in maturity.

Fastify example

// fastify-server.js const fastify = require('fastify')({ logger: true }); fastify.get('/', async (request, reply) => { return { msg: 'Hello from Fastify' }; }); fastify.listen({ port: 3000 }, (err, address) => { if (err) { fastify.log.error(err); process.exit(1); } fastify.log.info(`Fastify app running at ${address}`); });

Feels modern, right? You even get nice JSON logs without having to install anything extra.

So, Which One Should You Use?

Here’s the quick rundown.

Go with Express if:

  • You just want to build something quick.
  • You or your team already know it well.
  • You don’t care too much about performance and just want it to work.

Go with Fastify if:

  • You’re starting fresh and want modern features.
  • Performance actually matters for your use case.
  • You want structured request validation and automatic docs without cobbling together a bunch of packages.

Final Thoughts

Use the right tool for the job. Express is still good, but Fastify is making strong moves. If you're not stuck with legacy code or team constraints, Fastify feels like the better long-term play.

Either way, just build cool stuff.

Keep Your GoFiber Handlers Clean with Middleware Validation

If you’ve been building APIs with GoFiber, you’ve probably had that moment where your route handler starts to get a little... messy. Especially when you’re doing request validation right inside the handler.

Let’s talk about a simple tip to clean that up using middleware — it’s easy, reusable, and your future self will thank you.

😬 The Messy Way (We've All Done It)

Here’s what a typical handler might look like at first:

app.Post("/users", func(c *fiber.Ctx) error { type UserRequest struct { Name string `json:"name"` Email string `json:"email"` } var body UserRequest if err := c.BodyParser(&body); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Invalid request body", }) } if body.Name == "" || body.Email == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Name and Email are required", }) } // Do the thing return c.JSON(fiber.Map{"message": "User created"}) })

This works fine at first, but as your API grows, stuffing all the parsing and validation into your handlers gets old real quick.

✨ The Cleaner Way: Middleware

Let’s move the validation logic out of the handler and into a middleware. That way, your handler can focus on doing what it’s actually meant to do.

🧱 Step 1: Define Your Request Struct

type UserRequest struct { Name string `json:"name"` Email string `json:"email"` }

🧼 Step 2: Write a Middleware to Validate It

func ValidateUserRequest(c *fiber.Ctx) error { var body UserRequest if err := c.BodyParser(&body); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Invalid JSON body", }) } if body.Name == "" || body.Email == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Name and Email are required", }) } // Pass the validated body to the next handler c.Locals("userBody", body) return c.Next() }

🧑‍🍳 Step 3: Use It in Your Route

app.Post("/users", ValidateUserRequest, func(c *fiber.Ctx) error { body := c.Locals("userBody").(UserRequest) // Clean and easy return c.JSON(fiber.Map{ "message": "User created", "user": body, }) })

Nice and tidy. You’re only dealing with the stuff you care about inside the handler.

🏆 Why This Rocks

  • Separation of concerns – Validation and logic are in their own lanes.
  • Reusability – You can reuse the same middleware for other routes.
  • Testability – Easier to test your logic without worrying about request parsing every time.

💪 Bonus: Use a Validation Library

Want to step it up a notch? Add go-playground/validator for fancy rules like email format, string length, etc.

go get github.com/go-playground/validator/v10

Then tweak your middleware:

import "github.com/go-playground/validator/v10" var validate = validator.New() type UserRequest struct { Name string `json:"name" validate:"required"` Email string `json:"email" validate:"required,email"` } func ValidateUserRequest(c *fiber.Ctx) error { var body UserRequest if err := c.BodyParser(&body); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid body"}) } if err := validate.Struct(body); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()}) } c.Locals("userBody", body) return c.Next() }

Now your validation is way more powerful, but still just as clean.

👋 Final Thoughts

Keeping your GoFiber handlers clean doesn’t have to be complicated. With a little middleware magic, you can offload the grunt work like validation and keep your handlers laser-focused.

Try it out on your next API project. Your code (and teammates) will be happier for it.