/r/golang

Photograph via snooOG

Ask questions and post articles about the Go programming language and related tools, events etc.

Rules

1. Be friendly and welcoming.

Post is not in keeping with an inclusive and friendly technical atmosphere.

2. Be patient.

Remember that people have varying communication styles and that not everyone is using their native language. (Meaning and tone can be lost in translation.)

3. Be thoughtful.

Productive communication requires effort. Think about how your words will be interpreted. Remember that sometimes it is best to refrain entirely from commenting.

4. Be respectful.

In particular, respect differences of opinion.

5. Be charitable.

Interpret the arguments of others in good faith, do not seek to disagree. When we do disagree, try to understand why.

6. Be constructive.

Avoid derailing: stay on topic; if you want to talk about something else, start a new conversation. Avoid unconstructive criticism: don't merely decry the current state of affairs; offer—or at least solicit—suggestions as to how things may be improved. Avoid snarking (pithy, unproductive, sniping comments) Avoid discussing potentially offensive or sensitive issues; this all too often leads to unnecessary conflict. Avoid microaggressions

7. Be responsible.

What you say and do matters. Take responsibility for your words and actions, including their consequences, whether intended or otherwise.

8. Follow the Go Code of Conduct

As a part of the Go community, this subreddit and those who post on it should follow the tenets laid out in the Go Code of Conduct: https://golang.org/conduct

Treat everyone with respect and kindness. Be thoughtful in how you communicate. Don’t be destructive or inflammatory.

9. Must be Go Related

Posts must be of interest to Go developers and related to the Go language.

This includes: - Articles about the language itself - Announcements & articles about open source Go libraries or applications - Dev tools (open source or not) specifically targeted at Go developers

We ask that you not post about closed-source / paid software that is not specifically aimed at Go developers in particular (as opposed to all developers), even if it is written in Go.

10. Do Not Post Pirated Material

Do not post links to or instructions on how to get pirated copies of copyrighted material.

11. Job Posts Go in the "Who's Hiring?" Post

We have a monthly "Who's Hiring?" post that will stay pinned to the top of the subreddit. To avoid too much noise from companies, please post job openings there. Please keep in mind, this is for 1st party postings only. No 3rd party recruiters.

12. No GPT-generated or GPT-quality content.

No GPT or other AI-generated content is allowed as posts, post targets, or comments. This is only for the content itself; posts about GPT or AI related to Go are fine.

As GPT content is difficult to distinguish from merely low-quality content, low-quality content may be removed too. This includes but is not limited to listicles and "Go tutorials" that have no human voice and add nothing of their own.

Documentation

Community

/r/golang

285,420 Subscribers

2

Looking for simple and easy to use validation library for Golang

I’m searching for an easy to use validation library for Golang. It should have a sensible default validation errors and easy to extend

1 Comment
2024/12/04
14:20 UTC

6

Go backend architecture for 2-person SaaS (seeking advice)

Hey everyone,

I'm seeking advice from experienced developers since we're more tinkerers than traditional developers, please don't judge our code too harshly!

Context

We're two developers building an ambitious bootstrapped SaaS app.

After 2-3 years of development, our product is nearly mature enough for release, but we need to keep shipping features quickly.

However, we're noticing our backend code is becoming increasingly fragile. Our setup is a Go stateless REST API with a single Postgres database.

We've taken a pragmatic approach throughout development:

PHASE 1

Single file

PHASE 2

Split into multiple files (no folders)

handlers.go
main.go
config.go
...

PHASE 3 (current)

Introduced packages by folders

|--- /router
|    |--- router.go (route definitions)
|    |--- table1.go
|    |--- table2.go
|    |--- ...
|
|--- /middlewares
|    |--- middleware1.go
|    |--- middleware2.go
|    |--- ...
|
|--- /config
|    |--- config.go (env variables etc.)
|
|--- /database
|    |--- (all object models + migration management)
|    |--- ...
|
|--- /utils
|    |--- (helpers used across all API handlers for JSON parsing, standardize error returns...)
|
|--- /services
|    |--- services.go (initializes all services)
|    |--- data_migration.go (for managing data migrations)
|    |--- stripe.go (billing)
|    |--- emails.go (email sending for all API handlers)
|    |--- table1.go (reusable methods for all API handlers)
|    |--- table2.go
|    |--- ...
|
|--- /lib
|    |--- (external libs structs = AWS, Auth0, logger...)
|
|--- main.go (initializes all structs, handles dependency injection + starts server)

This structure has served us well until now!

It's been simple, with minimal context switching, few abstractions, and manageable complexity – perfect for shipping quickly and safely.

Current Challenges

However, we're now facing several challenges:

  1. Route and service files have grown extremely large, with some reaching around 4,000 lines of code
  2. We're encountering spaghetti dependency injection issues in the /services section, leading to questionable workarounds:
type Service struct {
    config           *config.Config
    utils            *utils.HandlerUtils
    Stripe           *Stripe
    aws              *lib.AWS
    productAnalytics *lib.ProductAnalytics

    Emails        *EmailsService
    Users         *UserService
    Organizations *OrganizationService
    //..
}

func NewServices(orm *lib.Orm, logger *lib.Logger, config *config.Config, stripe *Stripe, aws *lib.AWS, productAnalytics *lib.ProductAnalytics, utils *utils.HandlerUtils) *Service {

    emailsService := &EmailsService{
        orm:    orm,
        logger: logger,
        config: config,
    }

    usersService := &UserService{
        orm:    orm,
        logger: logger,
    }

    organizationsService := &OrganizationService{
        orm:    orm,
        logger: logger,
    }

    //..

    services := &Service{
        config:           config,
        Stripe:           stripe,
        aws:              aws,
        productAnalytics: productAnalytics,
        utils:            utils,
        Emails:           emailsFunctions,
        Users:            usersService,
        Organizations:    organizationsService,
        //...
    }

    services.Emails.services = services
    err := emailsService.InitCronsEmail()

    if err != nil {
        logger.Error("couldn't init cron transactional emails:", err)
    }

    services.Users.services = services
    services.Organizations.services = services

    //...

    return services
}
  1. CRONs and data migrations feel out of place as services – should they be structured differently?

  2. It's becoming unclear where to add shared code that needs different configurations across services

What would you recommend? We'd prefer to avoid introducing hexagonal architecture, Clean Code, or similar patterns, as they might slow us down and feel excessive for our needs.

4 Comments
2024/12/04
10:33 UTC

6

Diago release v0.9.1

Hi Gophers,
https://github.com/emiago/diago/releases/tag/v0.9.1

Diago as library aim is to be replacement for some current VOIP frameworks like Asterisk, where more control over media is needed.
Docs: https://emiago.github.io/diago/docs/getting_started/
Demo Examples: https://emiago.github.io/diago/docs/examples/

0 Comments
2024/12/04
09:07 UTC

163

Go 1.23.4 is released

You can download binary and source distributions from the Go website:
https://go.dev/dl/

View the release notes for more information:
https://go.dev/doc/devel/release#go1.23.4

Find out more:
https://github.com/golang/go/issues?q=milestone%3AGo1.23.4

(I want to thank the people working on this!)

17 Comments
2024/12/04
07:07 UTC

1

Fallback storage ideas

I'm building a web service that will connect to a DB. I'm toying with some ideas of how to maintain functionality while the DB is down, in case it ever goes down.

How would you do this? SQLite? Connect to a fallback clone? Cache things in ram until they can write again?

I've mostly been lucky enough in my career that I could just treat the DB as a given, and any hiccups didn't hurt too much, but I'm trying to build something that I want to be a bit more structurally sound.

Got any ideas?

14 Comments
2024/12/04
04:38 UTC

15

Advent of Code 2024 Day 1: Missing abs() for integers

Wrote a blog about this year's advent of code day 1. While solving the problem I was once again struck with the missing function for calculating absolute value for integers and decided to dig a lil deeper. You'll also find a small recap of how the abs() function for floats evolved over time in the standard library.

https://www.bytesizego.com/blog/aoc-day1-golang

Please do give it a read and let me know your thoughts!

1 Comment
2024/12/04
03:32 UTC

15

You asked for it: I created the ultimate Justfile version of my popular Go build system

Hi again Gophers! 👋

After my Ultimate Makefile post, many of you said "This is great, but I use just!" Well, I heard you loud and clear. So here it is - the complete port of ultimate-gomake to a Justfile that's just as powerful (pun intended 😉).

For those who missed the original: this is a build system that grows with your project, from tiny experiments to enterprise-scale applications. And now you can choose your preferred flavour: Make or Just.

Same great features, new command runner:

  • Starts lean but scales to enterprise
  • Sensible defaults you can easily override
  • Complete testing suite (unit, integration, e2e)
  • Cross-compilation that just works (still punning)
  • Seamless Docker and CI/CD integration
  • Database management tools
  • Developer goodies (hot reload, linting, security checks)
  • Auto-generated documentation
  • Monorepo support
  • Pretty output with progress emojis 🚀

The best part? If you're already using ultimate-gomake and want to switch, it's a drop-in replacement. All commands work the same way, just with just instead of make.

Original Makefile version: https://github.com/crazywolf132/ultimate-gomake
New Justfile version: https://github.com/crazywolf132/ultimate-gojust

2 Comments
2024/12/04
01:39 UTC

0

Can't Find GOROOT directory

Hello,
I am a newbie. I am using fedora and install go by using dnf install. Then in order to delete some packages, when I opened my home directory, I found folder named "go". I don't know why, suddenly panicked and deleted it using rm -rf. It didn't break anything, but then I decided to delete go completely and install again.

Now when I search the internet, I found that to delete go, I need to just delete go directory at /usr/local/go. And then, remove go related lines from /etc/profile and .bashrc. However, there is not any directory named "go" at /usr/local, and nothing is written related go at /etc/profile or .bashrc. When I run the code, go env GOROOT, it shows the location /usr. There is not anything related to go at /usr, too. When I run which go, it shows the location /usr/bin/go. There is not anything related go at there, too. However, go is installed, as I can use go command, write go version, and etc. How can I found the necessary directories and then delete go?

1 Comment
2024/12/03
23:52 UTC

4

Go iterators package

Ever since go 1.23 came out a few months ago, I've been practing writing iterators as they don't come as intuitive to me as I was hoping. I then decided to compile them all into one package called seqs and another seqs/transform for iterators that modify the input sequence (there's also a seqs2 and seqs2/transform2). I then put them all in a library that I've been calling goext as it's intended to 'extend' the go standard lib with iterators, common data structures and algorithms and more.

This is my first package intended for public use so I'm not confortable saying it's production ready just yet. I'd like to get some feedback from the community before I release version 1.0.

I'd appreciate any feedback.

https://pkg.go.dev/github.com/elordeiro/goext

11 Comments
2024/12/03
23:16 UTC

5

Go blown out Java in a load test I was performing

I was doing a load test using Vegeta, and the results were very surprising. Java was nowhere close to Go, especially when it had to deal with a large chunk of memory.
Linking the java code (spring boot) and Go code as well.

Go Code:- https://www.mashupstack.com/share/674f89a0b93ff

Java Code:- https://www.mashupstack.com/share/674f8ba47134b

With results here

**Go Results**

echo "GET http://localhost:8080/fetch" | vegeta attack -duration=10s -rate=5000 | vegeta report

Requests [total, rate, throughput] 48827, 4999.68, 3334.51

Duration [total, attack, wait] 14.1s, 9.766s, 4.333s

Latencies [min, mean, 50, 90, 95, 99, max] 230.208µs, 1.67s, 1.249s, 4.105s, 4.564s, 5.239s, 8.343s

Bytes In [total, mean] 1128360, 23.11

Bytes Out [total, mean] 0, 0.00

Success [ratio] *** 96.29%***

Status Codes [code:count] 0:1812 200:47015

___________________________________________

*Java Spring Framework Result*

echo "GET http://localhost:8080/fetch" | vegeta attack -duration=10s -rate=5000 | vegeta report

Requests [total, rate, throughput] 29385, 2913.56, 48.25

Duration [total, attack, wait] 39.358s, 10.086s, 29.272s

Latencies [min, mean, 50, 90, 95, 99, max] 225.708µs, 16.132s, 26.193s, 30.057s, 30.095s, 30.253s, 30.421s

Bytes In [total, mean] 24687, 0.84

Bytes Out [total, mean] 0, 0.00

Success [ratio] *** 6.46%*** nowhere near to Go

Status Codes [code:count] 0:27486 200:1899

_______________________________________________________

Note the success ratio for Go and throughput which is insanely high in comparison to Java.

And note the wait time. It is on the very higher side of Java. Go out of the box just simply works.

It was the same program, the same machine on both sides and Go simply outperformed Java in my testing.

Let me know what are your thoughts.

56 Comments
2024/12/03
23:06 UTC

0

Why we don't have pointer arithmetic with Go

Ok, so I know Go was made to be simple (and I fully encourage that). But pointer arithmetic is simple no ?

I mean it is simpler than extreme type conversion with unsafe package (I am having super weird lines of code that works but look awful 😖)

27 Comments
2024/12/03
23:04 UTC

7

🚀 New Net/Http request binder!

I've created a new request binder, compatible with net/http to bind requests (PathParams, QueryParams, Headers and Body) to Structs and Maps.

This is a partial rewrite of Echo binding methods, with some enhancements, to accept standard net/http requests.

Here is the repo:

https://github.com/gobigbang/binder

If you are interested, feedback is highly appreciated!

12 Comments
2024/12/03
22:29 UTC

110

I created the ultimate Makefile for Go projects that actually scales from tiny to enterprise

Hi fellow Gophers! 👋

You know that feeling when you're starting yet another Go project and thinking "ugh, time to copy-paste and modify that Makefile again"? Yeah, me too. That's why I built something I think you'll love - a Makefile that grows with your project and doesn't get in your way.

Here's what makes it special:

  • Starts lean but can handle enterprise-scale projects
  • Sensible defaults that you can easily tweak
  • Complete testing tools (unit, integration, e2e)
  • Cross-compilation that just works
  • Seamless Docker and CI/CD setup
  • Database management made easy
  • Developer goodies (hot reload, linting, security checks)
  • Auto-generated docs that actually look good
  • Works great with monorepos
  • Pretty output with progress emojis because why not? 🚀

Here's the cool part - it's totally modular. Only want the basics? No problem. Need more features later? Just flip a switch. It's like LEGO for your build system.

GitHub: https://github.com/crazywolf132/ultimate-gomake

53 Comments
2024/12/03
22:00 UTC

70

SecretFetch: A Go library that makes AWS Secrets Manager as easy as struct tags 🔐

Hey Gophers! 👋

I've just released SecretFetch, a Go library that makes working with AWS Secrets Manager as simple as using struct tags. No more hardcoding secrets or wrestling with complex AWS APIs!

Key Features:

  • 🎯 Dead simple API - just add struct tags and go!
  • 🚀 Built-in caching for better performance
  • ✨ Automatic secret validation
  • 🔄 Seamless AWS Secrets Manager integration
  • 🛡️ Type-safe secret management

Here's how simple it is to use:

type Config struct {
    DBPassword string `secret:"database/prod/password"`
    APIKey     string `secret:"api/prod/key"`
}
// That's it! SecretFetch handles the rest

Check it out on GitHub: SecretFetch

Feedback and contributions welcome! 🙌

15 Comments
2024/12/03
20:38 UTC

5

[Update] The plain TeX editor + Azure thermes

2 Comments
2024/12/03
20:16 UTC

3

Pion webRTC stream freezes after couple of seconds

Hello!

Just started working with Pion and its amazing ! works great but with one caveat, for some reason the video stream gets stuck after 30 - 90 seconds (varies heavily), after 20 seconds or so it gets lagish and then slowly returns to normal, only to repeat this cycle after couple of minutes - over and over, and Im not sure why.

As this is not my first webRTC backend (altho with python), I tried to switch devices, using different browsers, and even having my own flutter app running on my iPhone and android all experiencing the same fate.

The Go server only takes the track the client stream, and returns it (like the reflect example) + I use web sockets with gorilla to trickle ICE .

Im running this on a big server (1tb ram and many cores) so resources is not a problem for the server (also checked the docker stats for spikes or anything like that resource utilization stays coherent). webrtc-internals shows that the server really stops sending frames the whole time (inbound are 0 FPS and bitrate - but outbound liked just fine).

I think I have some context issue or miss handling packets in some way, but im too new in go to understand it alone.

This is a repo to replicate the issue.

https://github.com/VerioN1/webrtc-poc-go

main2.go is experiencing it way worse (less than 20 secs to freeze) so you can play around with it.

Any help would be much appreciated

0 Comments
2024/12/03
20:01 UTC

36

Cerbos PDP - Open source authorization solution (SDK for Go)

Hey! In case anyone here is thinking about implementing authorization in your Go lang apps - I wanted to share our OSS solution - Cerbos PDP. 

(We just hit 3k+ stars) https://github.com/cerbos/cerbos and here’s our SDK + guide for implementing authorization in Go https://www.cerbos.dev/ecosystem/go 

Here are some of Cerbos PDP’s key capabilities and updates:

  • Infinitely scalable RBAC and ABAC. Users can author role-based or attributed-based access control policies. As well as define an unlimited number of roles, user permissions, and access control policies without affecting performance.
  • Decoupled authorization decision point that extracts complex access control logic into centrally managed and versioned policies. Cerbos also provides a framework to comprehensively test and deploy policies. It reduces code complexity, bugs, security vulnerabilities, and multiple if/then/else conditions.
  • A plug-and-play & language-agnostic solution that works with any authentication/identity provider (Okta/Auth0, Active Directory, Entra ID, etc.) and seamlessly integrates into your existing infrastructure. 
  • Authorize anywhere. Cerbos’ stateless design enables it to be run anywhere in your own infrastructure:  in the cloud, across clouds, on-premise, at the edge, or directly on end user devices. Cerbos is optimized for sub-millisecond evaluation without having to synchronize data.
  • Centralized audit logs of all authorization requests help compliance with ISO27001, SOC2, and HIPAA requirements through real-time change logs for auditing access controls. 

PS. We just added an update that I think you’ll find valuable - The Cerbos server and the cerbosctl utility can now be installed on Nix environments using the new flake, and Go developers can now run Cerbos in-process using the new cerbos.Serve function from v0.39.0. This is useful for cases where running an external process is impossible or for running tests

Let me know what you think, if you have a moment.

1 Comment
2024/12/03
19:01 UTC

9

Quantum Safe Cryptography in Go

I saw that the crypto/mlkem package was already implemented in the git repo, but not yet released (https://github.com/golang/go/issues/70122), does anyone know when the new go version is going to be released? I am developing an application that needs quantum-safe encryption such as the Kyber/ml-kem algorithm, therefore I am looking for golang libraries that implement quantum-safe key-pair cryptography. I appreciate any help, thank you!

8 Comments
2024/12/03
18:21 UTC

1

Parsing JSON : map[string]any versus Struct

Hi all,

Is there a consensus on what is best practice to use when encoding JSON to be sent to the client? Im using both techniques (struct w/ json tags) in my code right now, but wondering if i should just stick with one or the other

15 Comments
2024/12/03
18:08 UTC

6

A BubbleTea exploration of TUIs and tasty drinks

I've been struggling a good bit with picking up bubbletea which just always felt far more complicated than it needed to be. So while I don't claim to be an expert given that I had 4 days off and was stuffed like a turkey, I started blogging the various stages of my journey. If anyone finds this useful I thought I'd share.

I'll keep on adding chapters while I gain more insights. Any thoughts/feedback or revelation oh how to make writing a TUI easier in go, I'd love to hear from you.

https://csgeek0x7bc.substack.com/s/codingprogramming

1 Comment
2024/12/03
17:57 UTC

13

How are you guys dealing with pgx pgtype boilerplate?

I'm interested to know what sort of patterns or abstractions you guys are using to deal with the boilerplate.

20 Comments
2024/12/03
15:37 UTC

0

Is there a way to do this without the generic?

Hey all,

I'm still learning go, sorry if this is dumb.

I am getting annoyed at functions that return multiple things and I really only care about the first. I want to be able to do quick dirty one liners instead of take in foo, _ := func() then do something with foo

So after stumbling around I wrote this function

func First[T any](vals ...any) T {
    return vals[0].(T) // unsafe, there's more checks in the real thing
}

I use it like this:

a := First[string](test_many()) // test_many returns (string, int, int, string)
fmt.Printf("%s\n", "hello "+a+" world")

Is there a way to get rid of the [string] and the generic? If I go with only variadic arguments, without the generic, I wouldn't be able to take the result and just add another string to it, since I can't add a string and an any without a cast (as far as I'm aware)

I tried a reflection approach as well but that flopped in the same way.

Can I condense First() more so it's more intelligent about the types? I come from languages that lack reflection so this is new to me and I want to know what's possible / where the hiccups are.

I want to be able to write First(test_many()) and the return to be string, not an any.

9 Comments
2024/12/03
02:53 UTC

0

Make package callable? package.Function() => package()

In the example below, I was able to create a package with a single function. The package name is helloWorld and the function name is HelloWorld.

To call the function, I need to use helloWorld.HelloWorld(). Is it possible to call the function by using helloWorld()? The helloWorld package is only going to have 1 function that will be made available for all other packages.

go.mod

module example.com/john/test

go 1.23.3

main.go

package main

import helloWorld "example.com/john/test/helloworld"

func main() {
	helloWorld.HelloWorld()
}

helloworld/hello.go

package helloWorld

import "fmt"

func HelloWorld() {
	fmt.Println("Hello World")
}
12 Comments
2024/12/03
01:51 UTC

4

Struggling to understand range based for loop behavior for a struct with slice

I am having a hard time understanding how range based for loops interact with structs that have slice fields. This was hard for me to figure out as it was a language misconception for me. I am relatively new in Go.

Consider this example with a struct and slice of this struct struct:

type MyStruct struct {
  identifier    int64
  content       []int
}

mySlice := make([]MyStruct, 0)
// here, added some elements to `mySlice`

later, when interacting with this using a range based for loop such as:

for _, elem := range mySlice {
  elem.content = append(elem.content, 10)
}

Why is this not modifying the original elem.content ? Since slices are "reference types", i was expecting this to modify the original slice. I understand that normally range based for loops create copies, but I am confused as to why elem is a deep copy and not a shallow copy(?). This was totally unexpected for me.

I guess my confusion also stems from the fact that when I assign one struct to another struct, the primitive variables are deep copied, but if there are any slice variables within the struct, they are shallow copied (slice descriptors are copied). I had another bug related to this in my code so I had to write a custom copier myself that does the deep copying work. I am confused because assignment seems to be different in behavior (i.e., does shallow copy) than this range based for loop behavior (i.e., does deep copy?). Am I missing something?

10 Comments
2024/12/02
23:32 UTC

48

Anyone doing AoC

EDIT: AoC is advent of code

Title pretty much says it all. Obv using go, no frameworks or libs.

I’m pretty new to go and decided to use it for this years AoC and put my solutions up on github.

Anyone else doing it and has a repo they’re willing to share?

Edit: My repo so far https://github.com/scyence2k/AoC2024 (day 2 is unfinished). I know the solutions aren't great but any feedback is welcome

59 Comments
2024/12/02
21:37 UTC

Back To Top