It seems like every middling company out there wants to bolt in popular architecture from other languages into Go, particularly Java enterprise patterns. Why not use the actual language or framework your engineers like instead?
I don't think Laravel is particularly GoF-ish, if that's what you mean. In terms of patterns it's mostly fairly simple.
> Why not use the actual language or framework your engineers like instead?
Go does not provide "enough" by itself to completely furnish my needs. And having a framework that uses common terminology and patterns allows you to get s__t done and not waste time bikeshedding.
Same reason IDEs — when you really know them — allow for quicker development compared to using primitive text editors with a bunch of third-party plugins duck-taped together. When you understand the framework, everything is written to the same standard, behaves in similar ways, and is where you expect it to be. Adding things like background job processing requires changing one line of config.
Also, one major thing I'm missing personally is automatically generated OpenAPI specifications + API documentation & API clients autogenerated from it. Last time I checked Go, you had to write the spec manually, which is just ridiculous — the code already has all the necessary info, and duplicating that effort is time-consuming and error-prone (the spec says one thing, the code does another). This may be out of date, but if it still isn't, it is enough to disqualify the stack completely for me.
Also, I don't think there anything similar in the Go world to these administration panels:
I get wanting to be productive and gravitating towards patterns you’re familiar with but in the end it’s all bloat. http can do routing and patterns and cookies and sessions. database/sql can do your DAL work. uuid (various implementations) work for user/tenant uid+oid obfuscation. JWT libs for auth. You can literally json.unmarshal your config for your whole application or use godotenv to use environment variables. template/html for views. Golang has batteries, it’s just you don’t know what you don’t know so you expect a certain perspective that isn’t how we do things. Like joining a new company, things are different here. If you spent some time to learn the “go way” you’d realize that you don’t need the bloat, you just need the structure. The “where I expect it”.
It depends on the framework and other stuff around it but you're right about the API documentation issue, there's godoc if you want to document functions but for something like API endpoints it's not what you'd find from openapi/swagger unless whatever you're using is adaptable to that and then whenever I was working with it an older spec of it too. Always fun to run into a client who expects this from working with most of their people and you're just drooling like a gopher at them but for now if you're writing something in go for pure performance I'm not 100 on what balances best between that and auto spec... Definitely choose an API framework in go that works out of the box for that if it's important. This may be better than when I tried it a couple years back
> automatically generated OpenAPI specifications + API documentation
I'd much rather have engineers write OpenAPI specification files by hand and then generate their server code from that file. Way easier to maintain and actually forces devs to have good documentation for their APIs.
I think it's the issues in "Go plus a few simple libraries". Frameworks come with all the extra features built in. If I need rate limiting, I can just open rate limiting docs and add it to my route, there is no need to search some library or blog post on the "best way" to implement rate limiting middleware in go.
It's a long list. It might be more productive to start with just one example: OpenAPI validation.
In large orgs with customer-facing APIs, it's imperative that you can validate and enforce OAS specifications against all routes. Customers need to know exactly what auth mechanisms they can use and shouldn't be enabled to call undocumented capabilities. It's also important from a practical perspective that developers can scaffold up new routes that are always-already bound to a specification. Depending on the context you either need to do "contract first" specification or "code first" generation based on type system introspection.
Go can let you knock something together yourself but as your team gets larger, the overhead of reviewing and marshaling your team's practices gets more and more difficult.
It's like the problem you have with NodeJS. It's very possible to assemble something that has easy to scaffold routes with strong type-to-spec validation, authn/z, no exposure of undocumented APIs. But without something like NestJS or Adonis each project becomes a special snowflake with no support for interop across repositories.
I want to write `framework init` or something like that and get the whole scaffolding done for me so that I can focus on business logic. I don't want to waste time integrating auth, OTEL logging/tracing/monitoring, SQL dynamic query building, parsing & validation, config management, i18n, unit/integration/e2e testing, routing, http/ws/grpc support, openapi generation, A/B testing, task queuing, background jobs, cron jobs, request control (deadlines, rate limiting, health checks), database migrations, live reloading.
I love that I at my workplace I can use a service template that wires everything together. And I don't understand why people want to do boring solved tasks over and over again.
> Why not use the actual language or framework your engineers like instead?
Consistency and predictability, but with a more convenient technology underneath.
I don't want to mess around with JDK runtimes or .NET. I don't want to experiment with various static packaging techniques and wonder whether any sort of reflection will be incompatible with that or any of the large frameworks that pre-date it will work. The runtimes themselves are good, but that's just busywork.
At the same time, I do want the ability to pick up a project made with a certain framework and approximately know how things work and how to do stuff. Less undocumented internal utilities and custom libraries, more of something predictable - controllers here, services there, repositories over here, here's how the ORM works that's tightly integrated with everything else, here's how you make a RESTful API. Think more like Angular than React to use a good front end example (e.g. a pre-packaged setup with batteries included). Or, you know, a direct comparison between the likes of Ruby on Rails, Laravel, Django, Spring Boot, ASP.NET etc., maybe not verbatim, but something consistent and close enough.
Go's standard library is also pretty good and includes a lot of stuff. The IDE experience is good (no need to even think that much about configuring your own code formatting), the compiler is good, platform support is good, runtime performance is good while the language remains higher level and easier than the likes of Rust, it's not hard to get everything into a single self-contained executable. There's numerous projects that have sprung up around that, even something like K3s (full Kubernetes distribtion) can be downloaded as a single file. Also really good for just CLI utilities, or full blown desktop apps (e.g. with Wails).
In other words, to take the technological advancements, shed the legacy cruft and still be able to have many projects be predictable and keep the productivity high, regardless of whether the greater language community is more interested in a grab bag of more self-contained libraries.
Well, just use the new generation of "microservice frameworks" in Java.
I personally believe that it is a much better language and ecosystem, and wouldn't bother using Go which has way more boilerplate, has pretty bad expressivity (so that libraries/frameworks will suffer from a usability perspective, e.g. look at JOOQs, a completely type-safe SQL query builder) for negligible benefits.
> Why not use the actual language or framework your engineers like instead?
Go does not provide "enough" by itself to completely furnish my needs. And having a framework that uses common terminology and patterns allows you to get s__t done and not waste time bikeshedding.
"Microservices are cattle, not pets."