The Valid method takes a context (which is optional but has been useful for me in the past) and returns a map. If there is a problem with a field, its name is used as the key, and a human-readable explanation of the issue is set as the value.
유효성 검사 방법: 선택적인 컨텍스트를 받아 문제가 있는 필드를 키로 하고 문제 설명을 값으로 하는 맵을 반환함. 이 방식은 과거에 유용했음을 언급함.
I used to do this, but ever since reading Lexi Lambda's "Parse, Don't Validate," I've found validators to be much more error-prone than leveraging Go's built-in type checker.
유효성 검사 대신 파싱: Lexi Lambda의 "Parse, Don't Validate"를 읽은 후, Go의 내장 타입 검사기를 활용하는 것이 유효성 검사보다 오류 가능성이 낮다고 느낌.
For example, imagine you wanted to defend against the user picking an illegal username. Like you want to make sure the user can't ever specify a username with angle brackets in it.
사용자 이름 유효성 검사 예시: 사용자가 꺾쇠 괄호가 포함된 불법적인 사용자 이름을 선택하지 못하도록 방어하는 상황을 상상함.
With the Validator approach, you have to remember to call the validator on 100% of code paths where the username value comes from an untrusted source.
유효성 검사기 접근법의 문제점: 불신할 수 있는 출처에서 온 사용자 이름 값에 대해 모든 코드 경로에서 유효성 검사기를 호출해야 하는 부담이 있음.
Instead of using a validator, you can do this:
유효성 검사 대안 제시: 유효성 검사기를 사용하는 대신, 다른 방법을 제안함.
That guarantees that you can never forget to validate the username through any codepath. If you have a Username object, you know that it was validated because there was no other way to create the object.
객체 생성을 통한 유효성 보장: Username 객체를 생성하는 과정에서 유효성 검사가 이루어지므로, 어떤 코드 경로를 통해서도 유효성 검사를 잊을 수 없게 됨.
I really like Mat Ryer's work, and I've applied most of the ideas in the 2018 version of this article to all of my Go projects since then.
Mat Ryer의 작업 선호: Mat Ryer의 작업을 매우 좋아하며, 2018년 버전의 기사에 나온 대부분의 아이디어를 자신의 Go 프로젝트에 적용함.
The one weak spot for me is this aspect:
약점 지적: 문제가 되는 부분에 대해 언급함.
This has always felt wrong to me, but I've never been able to figure out a better solution.
문제에 대한 해결책 부재: 잘못된 것 같지만, 더 나은 해결책을 찾지 못함을 표현함.
It means that a huge chunk of your code has a huge amount of unnecessary shared state.
공유 상태의 문제: 코드의 큰 부분이 불필요한 공유 상태를 가지고 있음을 지적함.
I often end up writing HTTP handlers that only need access to a tiny amount of the shared state.
HTTP 핸들러와 공유 상태: HTTP 핸들러가 매우 적은 양의 공유 상태에만 접근해야 하는 경우가 많음을 언급함.
Nothing against Mat Ryer, as his pattern is the best I've found, but I still feel like there's some better solution out there.
Mat Ryer의 패턴에 대한 존중: Mat Ryer의 패턴이 지금까지 찾은 것 중 최고라고 하면서도, 여전히 더 나은 해결책이 있을 것 같다는 느낌을 표현함.
one of my biggest pet peeves is when people take a Config object, which represents the configuration of an entire system, and pass it around mutably.
Config 객체 사용에 대한 불만: 전체 시스템의 설정을 나타내는 Config 객체를 변경 가능하게 전달하는 것에 대한 큰 불만을 표현함.
When you do that, you're coupling everything together through the config object.
Config 객체를 통한 결합 문제: Config 객체를 통해 모든 것을 결합시키는 문제점을 지적함.
I've worked on systems where you had to configure the parts in a specific order in order for things to work, because someone decided to write back to the config object when it was passed to them.
Config 객체의 순서 의존성 문제: Config 객체를 전달받은 사람이 그것에 다시 쓰기를 결정함으로써, 부품을 특정 순서로 구성해야만 시스템이 작동하는 경우에 대해 경험을 공유함.
Or another case was where I've seen it such that you couldn't disable a portion of the system because it wrote data into the config object that was read by some other subsystem later.
Config 객체와 시스템 부분의 비활성화 문제: Config 객체에 데이터를 쓰고, 그것이 나중에 다른 하위 시스템에 의해 읽혀져서 시스템의 일부를 비활성화할 수 없는 경우를 목격함.
The pattern of "your configuration is one big value, which is mutable" is one of the more annoying patterns that I've seen before, both in Go and in other languages.
변경 가능한 단일 대형 설정 패턴에 대한 비판: Go와 다른 언어 모두에서 본 "설정이 하나의 크고 변경 가능한 값"이라는 패턴에 대해 불편함을 표현함.
I agree with a lot of this, I'll add my own opinions:
의견 동의 및 추가: 많은 부분에 동의하며 자신의 의견을 추가함.
I would pass a waitgroup with the app context to service structs.
Waitgroup과 앱 컨텍스트 전달 제안: 서비스 구조체에 앱 컨텍스트와 함께 waitgroup을 전달하는 것을 제안함.
This way the interrupt can trigger the app shutdown via the context and the main goroutine can wait on the waitgroup before actually killing the app.
앱 종료를 위한 인터럽트와 waitgroup 활용: 인터럽트가 컨텍스트를 통해 앱 종료를 트리거할 수 있고, 메인 고루틴이 앱을 실제로 종료하기 전에 waitgroup에서 대기할 수 있음을 설명함.
If writing a CLI program, then testing stdout, stdin, stderr, args, env, etc. is useful.
CLI 프로그램 테스트의 유용성: CLI 프로그램을 작성할 때 stdout, stdin, stderr, args, env 등을 테스트하는 것이 유용함을 언급함.
But for an http server, this is less true.
HTTP 서버에 대한 다른 접근: HTTP 서버의 경우 위의 테스트가 덜 유용함을 지적함.
I would pass structured config to the run function to let those tests be more focused.
구조화된 설정 전달을 통한 테스트 집중: 더 집중된 테스트를 위해 구조화된 설정을 run 함수에 전달할 것을 제안함.
I disagree with parsing templates using sync.Once in a handler because I don't think handlers should do template parsing at all.
핸들러에서의 템플릿 파싱에 대한 반대: 핸들러가 템플릿 파싱을 전혀 하지 않아야 한다고 생각하기 때문에 sync.Once를 사용한 템플릿 파싱에 동의하지 않음.
I would do this when the app starts: if the template cannot be parsed, the app should not become ready to receive any requests and should rather exit with a non-zero exit code.
앱 시작 시 템플릿 파싱 제안: 앱이 시작될 때 템플릿 파싱을 수행하고, 파싱할 수 없다면 앱이 요청을 받을 준비가 되지 않아야 하며, 0이 아닌 종료 코드로 종료해야 함을 제안함.
I found fx to be a super simple yet versatile tool to design my application around.
fx 도구의 간단함과 다재다능함: fx를 매우 간단하면서도 다재다능한 도구로 찾아 애플리케이션 설계에 활용함.
All the advice in the article is still helpful, but it takes the "how do I make sure X is initialized when Y needs it" part completely out of the equation and reduces it from an N*M problem to an N problem.
기사의 조언과 fx의 이점: 기사의 모든 조언이 여전히 도움이 되지만, fx는 "Y가 필요할 때 X가 초기화되었는지 어떻게 확실히 할 것인가"라는 문제를 완전히 제거하고 N*M 문제를 N 문제로 줄임.
I've used quite a few dependency injection libraries in various languages over the years (and implemented a couple myself) and the simplicity and versatility of fx makes it my favorite so far.
fx의 선호도: 여러 언어에서 다양한 의존성 주입 라이브러리를 사용해왔고 몇 가지를 직접 구현하기도 했지만, fx의 단순성과 다재다능함이 지금까지 가장 좋음.
I've recently been playing with ogen:
ogen 사용 경험: 최근에 ogen을 사용해봄.
Write openapi definition, it'll do routing, definition of structs, validation of JSON schemas, etc.
openapi 정의와 ogen의 기능: openapi 정의를 작성하면 ogen이 라우팅, 구조체 정의, JSON 스키마 유효성 검사 등을 수행함.
All I need to do is implement the service.
서비스 구현의 단순화: 서비스를 구현하는 것만 필요함을 언급함.
Validating an integer range for a querystring parameter is just too boring. And too easy to mistype when writing it manually.
쿼리스트링 파라미터의 정수 범위 유효성 검사의 단점: 쿼리스트링 파라미터에 대한 정수 범위 유효성 검사가 지루하고, 수동으로 작성할 때 오타가 나기 쉬움을 지적함.
Anyways, so far only been playing, so haven't found the bad parts yet.
ogen에 대한 초기 평가: 아직까지는 ogen을 실험적으로 사용하고 있으며, 나쁜 점을 발견하지 못함.
Great article with lots of interesting ideas. Can't believe I didn't know about signal.NotifyContext. Finally I'll be able to actually rememeber how to respond to signals instead of copy-pasting that between projects.
기사와 signal.NotifyContext에 대한 긍정적 평가: 많은 흥미로운 아이디어가 담긴 훌륭한 기사라고 평가하며, signal.NotifyContext에 대해 알지 못했던 것에 놀라움을 표현함. 프로젝트 간에 복사-붙여넣기를 하지 않고 신호에 어떻게 반응해야 하는지 기억할 수 있게 됨.
I like a lot of what they've done here. My testing looks a bit different however.
기사의 접근 방식에 대한 호감과 테스트 방식의 차이: 기사에서 한 많은 것들을 좋아하지만, 자신의 테스트 방식은 조금 다름을 언급함.
In my newTestServer, I spin up a server with fakes for my dependencies.
의존성을 위한 가짜 서버 생성: 의존성을 위한 가짜 서버를 생성하는 방식을 사용함.
If I want to test a dependency error, I replace that property with a fake that will return an error.
의존성 에러 테스트 방법: 의존성 에러를 테스트하고 싶을 때, 에러를 반환할 가짜로 해당 속성을 교체함.
I can validate my error paths. I can validate my log entries. I can validate my metric emission. I can validate timeouts and graceful shutdowns.
다양한 검증 가능성: 에러 경로, 로그 항목, 메트릭 발생, 타임아웃, 그리고 우아한 종료 등을 검증할 수 있음.
After the server starts, I inspect to determine which port it is running on (default is :0 so I have to wait to see what it got bound to).
서버 시작 후 포트 검사: 서버가 시작된 후 어떤 포트에서 실행되고 있는지 검사함 (기본값은 :0이므로 어떤 포트에 바인딩되었는지 확인하기 위해 대기해야 함).
My "unit" tests can test at the handler level or the http level, making sure that I can fully test the code as the users of my system will see it, exercising all middleware or none.
단위 테스트의 범위: "단위" 테스트는 핸들러 수준이나 HTTP 수준에서 수행할 수 있으며, 시스템 사용자가 보게 될 코드를 완전히 테스트할 수 있도록 모든 미들웨어를 사용하거나 사용하지 않음.
I can spin up N instances and run my tests in parallel.
병렬 테스트 실행: N개의 인스턴스를 생성하고 테스트를 병렬로 실행할 수 있음.
I don't write go, but I like these patterns. Feels fairly universal for testable code.
Go 작성 경험 부재와 패턴 선호: Go를 작성하지 않지만, 이러한 패턴을 좋아하며, 테스트 가능한
Hacker News 의견