Don't Make this Golang Beginner Mistake!

Anthony GG
28 May 202408:56

Summary

TLDRIn this video, the speaker discusses common mistakes made by Go developers, particularly in handling database connections within a Kafka consumer setup. They emphasize the importance of abstraction to avoid hard dependencies on specific database technologies. The speaker introduces the concept of a 'log persister' interface to demonstrate how to implement dependency injection, allowing for more flexible and maintainable code. They also promote their private community, 'The Total Coder,' where they provide weekly assignments and live streams to review code and offer insights.

Takeaways

  • 📘 The speaker emphasizes the simplicity and readability of the Go language, but notes a common mistake made by many, especially newcomers.
  • 👨‍🏫 The Total Code community is mentioned as a private space where assignments are sent out weekly for members to solve in any language, predominantly Go.
  • 🎥 The speaker conducts live streams to review assignments and resumes, highlighting common issues to help members improve their coding practices.
  • 🔍 The script discusses a specific assignment related to log ingestion using Kafka, where the participant made a common mistake with database connections.
  • 🔗 The mistake identified was the instantiation of a new MongoDB client within a loop, which is inefficient and not a good practice for handling large volumes of data.
  • 🔄 The speaker points out a structural problem in the code, where the hard dependency on a specific database client makes the code inflexible for different storage solutions.
  • 🔑 The solution proposed is to use an interface, such as 'LogPersister', to abstract the database operations and allow for more flexible and maintainable code.
  • 🔄 By using dependency injection with the 'LogPersister' interface, the code becomes decoupled from specific implementations, making it easier to switch or test different storage solutions.
  • 🛠️ The importance of good Go practices is stressed, such as using interfaces and context as the first argument in functions, to align with common third-party library usage.
  • 📚 The speaker invites viewers to join the Total Code community for more learning opportunities and to avoid common mistakes in Go programming.
  • 👍 The script concludes by encouraging viewers to reflect on their coding habits, learn from the discussed mistake, and engage with the community for further improvement.

Q & A

  • What is the main issue the speaker identifies with the code in the script?

    -The main issue is that the code makes a new MongoDB client connection every time it processes a log, which is inefficient and not a good practice, especially when dealing with a high volume of logs.

  • What is the speaker's recommendation to avoid creating a new MongoDB client in each iteration of the loop?

    -The speaker suggests using an interface to abstract the database client creation, allowing for more efficient and flexible handling of different types of persistent storage.

  • What is the term used for the practice of creating a new database connection for each operation?

    -The term used is 'overkill', as it implies unnecessary complexity and inefficiency in the code.

  • What is the purpose of the 'total code' private community mentioned by the speaker?

    -The 'total code' private community is a place where the speaker sends out weekly assignments for members to solve, and then reviews those assignments in a private live stream, offering feedback and guidance.

  • What is the benefit of using an interface in the context of the script's code?

    -Using an interface allows for dependency injection and makes the code more modular and flexible, enabling the use of different types of persistent storage without modifying the core logic of the application.

  • What is the term for the technique where a specific implementation is replaced with a more general interface?

    -The term is 'abstraction', which helps to simplify the code and make it more maintainable and scalable.

  • What does the speaker suggest as an alternative to hard-coding the MongoDB client in the consume function?

    -The speaker suggests creating an interface called 'log persister' with a method 'persist log', which can then be implemented by different types of storage systems.

  • What is the advantage of using dependency injection in the context of the script?

    -Dependency injection allows for more testable and maintainable code by decoupling the specific implementation of a service from the code that uses it.

  • What is the 'context' argument mentioned in the script, and why is it important?

    -The 'context' argument is a way to pass request-scoped values across API boundaries and is important for managing request lifecycle, such as timeouts and cancellations.

  • What does the speaker mean by 'no-op' in the context of the script?

    -A 'no-op' (no operation) is a function or method that does nothing. In the context of the script, it could be used as a placeholder when no persistence is required.

  • What is the speaker's advice for those who want to improve their understanding of Go (Golang)?

    -The speaker suggests joining his Discord community, the private 'total code' community, or buying his courses to learn more about Go and improve their coding skills.

Outlines

00:00

📝 Common Mistakes in Golang Projects

In this paragraph, the speaker discusses the simplicity and readability of the Golang language, yet points out a recurring mistake made by many developers, particularly newcomers. The mistake isn't due to a lack of skill but rather a lack of awareness of best practices. The speaker introduces their private community, 'Total Code,' where they assign tasks to members and review their work in live streams. The focus is on a specific assignment related to log ingestion using Kafka, where a member made a good attempt but fell into the common trap of creating new database connections within a loop, which is inefficient. The speaker emphasizes the need for abstraction to avoid hard dependencies and suggests using interfaces to improve the code structure.

05:00

🔍 Abstracting Dependencies in Golang

The second paragraph delves into the concept of dependency injection and abstraction in Golang. The speaker critiques the hard dependency on a MongoDB client within a Kafka consumer function and suggests using an interface to abstract the persistence logic. By defining an interface with a 'persistLog' method, the speaker demonstrates how to pass this interface as a dependency to the Kafka consumer, allowing for flexibility in choosing the persistence method, such as MongoDB, Elasticsearch, or even a no-operation (no-op). This approach not only improves the code's maintainability but also its scalability, making it easier to adapt to different storage solutions or testing scenarios. The speaker encourages developers to understand and apply these principles to stand out in technical interviews and offers resources like Discord communities and courses for further learning.

Mindmap

Keywords

💡Goang

Goang is a misspelling or colloquial reference to the Go programming language, which is known for its simplicity and readability. In the video, the speaker mentions that many people have a good grasp of Go because it is 'very simple' and 'very easy to read and write.' The term is used to set the context of the programming language being discussed throughout the video.

💡Total Code

Total Code refers to the speaker's private community, which is a platform where members receive weekly assignments to solve in any programming language, with a majority opting for Go. The community provides a space for peer review and learning, as the speaker mentions conducting live streams to review assignments and resumes.

💡Assignment

An assignment in this context is a task or problem given to the members of the Total Code community to solve using a programming language. The video discusses an example of an assignment involving log ingestion and Kafka implementation, highlighting common mistakes made by participants.

💡Kafka

Kafka is a distributed streaming platform used for building real-time data pipelines and streaming apps. It is mentioned in the script as the technology the community member used for the log ingestion assignment, where JSON data representing a log file is produced and consumed on a Kafka queue.

💡MongoDB

MongoDB is a NoSQL database that stores data in a JSON-like format. In the video, the speaker points out that the community member's code instantiates a new MongoDB client within a loop, which is not a good practice due to the overhead of creating new connections repeatedly.

💡Interface

In Go programming, an interface is a type that specifies a method set which any other type can implement. The speaker suggests using an interface, named 'log persister' in the script, to abstract the database persistence logic, allowing for more flexible and maintainable code.

💡Dependency Injection

Dependency injection is a design pattern where an object's dependencies are provided to it, rather than the object creating or requesting its own dependencies. The speaker recommends using dependency injection by passing the 'log persister' interface to the Kafka consumer to decouple the consumer from the specific persistence implementation.

💡Structural Problem

A structural problem in code refers to an issue with the organization or architecture of the code that makes it inflexible or difficult to maintain. The video identifies a structural problem where the Kafka consumer is tightly coupled with the MongoDB client, making it hard to switch to a different persistence mechanism.

💡Persist

To persist data means to store it in a way that it can be retrieved and used later. In the context of the video, the community member's task was to consume log data and persist it efficiently in a persistent store, such as MongoDB or Elasticsearch.

💡Context

In Go, a context is used to pass request-scoped values and cancellation signals across API boundaries and between processes. The speaker emphasizes the importance of including a context as the first argument in interfaces, especially for third-party libraries that use context for managing request lifetimes.

💡No-op

A no-operation (no-op) is an empty operation that does nothing. The speaker uses the term to illustrate that the 'log persister' interface could be implemented in such a way that it does not persist anything, which might be useful during testing phases or other scenarios where persistence is not required.

Highlights

The speaker emphasizes the simplicity and readability of the Go language but notes a common mistake made by many developers.

Introduction to the Total Code private community where weekly assignments are given and reviewed.

The importance of learning from mistakes and the role of the Total Code community in facilitating this learning process.

A detailed review of a private community member's assignment, highlighting a mistake related to database connections in Go.

The inefficiency of creating a new MongoDB client within a loop for log consumption in a Kafka implementation.

The structural problem of hard dependencies in Go code, particularly with database clients.

The concept of dependency injection as a solution to hard dependencies in Go code.

The introduction of an interface, 'LogPersister', to abstract the persistence mechanism in Go code.

The benefits of using interfaces for dependency injection, allowing for more flexible and maintainable code.

A live coding example demonstrating the implementation of the 'LogPersister' interface in a Kafka consumer.

The elimination of hard dependencies by passing the 'LogPersister' interface as an argument to the Kafka consumer.

The ability to easily switch between different persistence mechanisms by simply changing the implementation of the 'LogPersister' interface.

The importance of context in Go interfaces, especially when dealing with third-party libraries.

A discussion on the common mistake of not abstracting dependencies in Go, and how to avoid it.

The speaker's invitation for viewers to join the Total Code community or Discord for more learning opportunities.

The speaker's offer of courses and live streams for those interested in learning more about Go.

A call to action for viewers to share their thoughts and experiences with the discussed concepts in the comments.

The conclusion of the video with a reminder of the value of learning from mistakes and the resources available for Go developers.

Transcripts

play00:00

so after doing a lot of reviews recently

play00:02

I see that a lot of people have a very

play00:04

good grasp of goang because it's a very

play00:06

simple language very easy to read and

play00:09

very easy to write but I see people

play00:13

making the same mistake over and over

play00:15

and it's not basically a skill issue

play00:17

it's just something that you need to

play00:18

learn and if nobody tells you it you

play00:20

will never learn that's why I'm here at

play00:22

the total code is my private community

play00:24

and each week I sent out an assignment

play00:27

that you can solve right you can solve

play00:29

that in any language as you want but

play00:31

most people solve that in goang and by

play00:34

the end of the week most likely on

play00:35

Sundays what I do is I basically uh do a

play00:38

private live stream for the members of

play00:40

that Community where I review resumes

play00:43

but I also review your assignments or

play00:45

other projects so this is basically an

play00:47

assignment of somebody from my private

play00:48

Community he did a very good job but um

play00:51

he made a mistake that I see a lot of

play00:54

people making especially if you're new

play00:57

to golang it's nothing to do with your

play00:58

skill issues it's just something you

play01:00

don't know and you need to learn that

play01:02

right and that's why we are here so uh

play01:05

hey if you're interested in the total

play01:06

coder Community you can uh find that in

play01:10

the link down below all right so let's

play01:14

get started so the previous assignment

play01:15

we needed to do something with loog

play01:17

ingestion uh and he his implementation

play01:20

was more of a Kafka implementation and

play01:23

let me show you what's going on here so

play01:24

we are producing some Json data which is

play01:27

representing a log file and we produce

play01:30

that on a Kafka queue right and of

play01:32

course if you produce on a Kafka queue

play01:33

we're also going to consume from that

play01:35

queue and basically this is the Kafka

play01:39

consumer structure which holds some data

play01:41

which holds some some variables here and

play01:44

the problem is hereat right so very

play01:47

simple it's going to consume heat it's a

play01:49

for loop it's going to read a message

play01:51

it's going to basically Marshall that

play01:53

into an log data because the assignment

play01:55

was hey we're going to provide you some

play01:57

log data and you need to basically

play01:59

consume that and store that efficiently

play02:01

in some kind of a persistent store you

play02:03

can choose whatever that is mongodb

play02:05

elastic search whatever right you could

play02:07

pick whatever you want and the problem

play02:10

is here right so because this is a loop

play02:12

right every time we consume he's going

play02:15

to actually two mistakes here each time

play02:18

we going to instantiate a new mongodb

play02:21

client right so we're going to make a

play02:22

new mongodb connection which is not a

play02:24

good practice because if you're

play02:26

producing a lot of logs and you're

play02:28

consuming a lot of stuff you're each

play02:30

time going to create this new client

play02:32

which is basically a little bit of an

play02:34

Overkill right and once that client is

play02:37

basically instantiated we are going to

play02:38

insert that into a DB and send the A and

play02:41

call it a day so from a first inspection

play02:46

of this scol there's nothing really

play02:47

wrong with it right it works perfectly

play02:49

fine uh just well this could be more

play02:52

optimized like I mentioned this client

play02:55

but there is basically a little bit of a

play02:58

structural problem here right because

play03:01

what is going to happen if we want to

play03:04

say Hey listen right now we do uh a

play03:06

Mongol persistent store but what if we

play03:09

want to use elastic search or we want to

play03:11

use something else right uh we want to

play03:13

write it to dis or we don't want to do

play03:15

anything at all because we're in a test

play03:16

phase or something we want to just have

play03:18

a uh we just want to log it out or

play03:20

something we don't want to persist it so

play03:22

if we want to do that each time we

play03:24

basically need to or we need to write a

play03:26

new function or we're going to basically

play03:28

just comment this out or Del it and make

play03:31

a new implementation here right for

play03:32

example elastic search or something so

play03:35

you can see this basically a problem a

play03:37

structureal problem actually it's a

play03:39

dependency problem why well because this

play03:43

client here this moongo client is

play03:45

completely encapsulated into this

play03:48

consume function so it's a very hard

play03:50

dependency right this kka consumer

play03:52

depends so hard on this client

play03:55

that it cannot yeah it's just a very

play03:58

hard dependency it's not an AB abstract

play04:00

type right so in goang how is a very

play04:02

common mistake and it's not only this is

play04:04

just a Kafka example but it's basically

play04:07

just the repository the DB um dependency

play04:10

a lot of people tend to forget to

play04:12

abstract way right so how can we solve

play04:15

that well it's actually very simple

play04:17

right I'm going to just do some some

play04:18

pseo code here instead of basically

play04:20

creating your moo client here what he

play04:23

needs to do is it could make an

play04:24

interface for example uh a persistor

play04:27

actually it it's locked so we could do

play04:29

something like a log persister and it's

play04:31

going to be an interface and what could

play04:34

be a good interface design here it could

play04:37

be something like

play04:38

persist um persist log for example and

play04:42

as a good goaling engineer we're going

play04:44

to give this a context context right and

play04:47

then because it's an interface and

play04:49

especially actually in a lot of

play04:51

functions you want to have a context as

play04:53

a first argument but espe specifically

play04:56

for these interfaces because um yeah

play05:00

a lot of these thirdparty libraries like

play05:02

MB or or elastic search or whatever they

play05:05

use context right so if you have an

play05:07

interface that basically supports that

play05:11

that's basically a big win and it's a

play05:13

very very good practice to do so persist

play05:16

log and we going to have I think it is

play05:18

data log data something like that right

play05:21

and of course an error right this could

play05:22

be the log persist interface and the

play05:24

only thing we need to do is say Hey

play05:26

listen we're going to actually embed

play05:28

well embed we're going to uh attach is

play05:31

also not a good word how do you call

play05:32

that we're going to basically provide

play05:33

this persist you could say uh persistor

play05:37

for example can I actually write this

play05:39

persist is going to be a log persist

play05:41

interface right and if you want to for

play05:44

example new Kafka consumer it's going to

play05:46

take a Kafka config but it's also going

play05:47

to take for example the uh

play05:51

persistor which is going to be the log

play05:53

persistor right and then I'm going to

play05:54

say persistor here is the persistor that

play05:56

we provide as an argument which is

play05:58

basically H some kind of dependency

play06:01

injection right there a very big rabbit

play06:03

hole we can go into this uh but that's

play06:05

what I call dependency injection with

play06:07

this interface provided into this Kafka

play06:10

consumer structure and right now U we

play06:12

basically completely abstracted the way

play06:15

how our persist is going to persist here

play06:18

right so we can actually

play06:20

completely what's going on here we can

play06:22

completely uh delete this thing and

play06:24

instead

play06:25

of connecting it's already connected

play06:28

right it's already in entiated uh

play06:30

because you're going to provide that in

play06:31

the new kka consumer uh constrictor

play06:34

function whatever you want to call that

play06:36

and the only thing we need to do is

play06:37

basically say if R is going to be uh is

play06:40

the c. persist do persist log and we're

play06:44

going to take in a context do we have

play06:46

that yes we have one that's already a

play06:49

win the context here and then we going

play06:51

to put in the data which is the log data

play06:54

here and then if the error is not n we

play06:57

are basically going to copy some stuff

play07:00

from here like this copy that paste that

play07:03

in delete this and save and that's going

play07:08

to be the code right of course we need

play07:11

to change some other stuff uh because

play07:13

yeah right now we have an extra argument

play07:15

here in um new Kaa consumer but it

play07:17

doesn't really matter right this is

play07:19

completely out of scope so right now you

play07:21

can see that if we want to consume it's

play07:22

just going to call the abstract the

play07:25

interface basically from the persistor

play07:27

actually look at that I'm making this

play07:29

small uh typo mistakes here

play07:33

persister uh just like that and of

play07:38

course we need to pers look at that man

play07:42

the pers just like that voila now it's

play07:44

perfectly fine so right now we don't

play07:46

depend on a specific uh persisting type

play07:49

like MB or elastic search right now we

play07:51

just basically depends on the interface

play07:53

and anything that has the persist log um

play07:57

function or method attached to it uh

play07:59

basically uh is eligible to uh be

play08:02

inserted as this argument in a new

play08:04

consumer can be elastic search could be

play08:07

Mong be could be whatever you want could

play08:09

be a no op it could be uh whatever you

play08:12

want right as long as it basically uh

play08:14

implements this persist log method so

play08:17

and this is a very common mistake uh of

play08:20

course the code will work right the code

play08:22

will work like he did but like I said if

play08:24

you want to do an interview assignment

play08:26

and they see that you basically

play08:27

understand that you need to abstract

play08:28

that out

play08:30

um you're going to have yeah I think

play08:32

you're going to have a more better

play08:33

chance than people that do not do that

play08:35

right so let me know if you make the

play08:37

same mistake or uh that you learned this

play08:39

or whatever let me know in the comments

play08:40

what you think about that and of course

play08:42

hey if you want to learn more about

play08:43

goang like I said join my Discord

play08:45

Community or join the private Community

play08:47

or buy some of my courses whatever uh

play08:49

that's all up to you and I'm looking

play08:51

forward to see you in one of my live

play08:53

streams or next videos peace out

Rate This

5.0 / 5 (0 votes)

相关标签
GoLangCode ReviewsCommunityKafkaMongoDBBest PracticesDependency InjectionAbstractionPerformance OptimizationProgramming Tips
您是否需要英文摘要?