How To Structure Your Golang (API) Projects!?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up everyone in this video I'm going to show you or teach you my best practices on how to structure project in golang it's going to be specifically uh focused on HTTP stuff API servers and all that stuff but most of the things will reflect for all kinds of use cases you're going to do in goal line before we continue if you like the videos I'm providing to you please consider subscribing to my channel give me a thumbs up leave some questions in the comments and jump into the Discord let's go so basically um yes what I'm going to do is I'm gonna teach you or show you how I do things right it's my best practices it does not mean that it's the best practice in my opinion there is no such thing like the perfect idiom it's all about things that work at a big scale right so and I see a lot of people over engineering their project uh creating all these folders necessary right so the main goal to remember the main goal to take away is don't over complicate stuff don't create useless folders keep things small because in golang it's very easy to uh stumble into circular dependencies and it's very hard you're gonna have a hard time to refactor all that stuff especially if you have a lot of code it's easier to scale your folders up over time than scale down over time right that's the the main thing what's going on with this mic yes so uh main your your main function is basically where you're going to initialize everything right what I'm doing is for example I always make a listen address which is going to be a flag string I'm going to try it to write some stuff out a very Play-Doh coded uh to show you guys a real example because otherwise you're not going to learn anything so we're going to say flag string is going to be listen and then you give a default value which is the whole Grail of ports 3000 and then you give it a usage you could say this is the server address the server address whatever right this is the listen address and then you could say flag parse uh like this and then you have your listen edited which you can give to your server so what I'm always doing is the next thing is I'm create a folder and it's going to be API right and the API folder is where I create a server and that server will um is basically where I'm gonna attach all my HTTP or API handlers too so I'm going to say package API then I'm going to say type server which is going to be a strict I'm going to give this a listen added right which is going to be a string and I'm also going to show you how to add your data layer very important because a lot of people also ask me hey how do I attach how do I access my database in in my HTTP and all that stuff that's very easy I'm going to show you later on we're going to build things up so we have our server here then I'm going to say new service with a listen added and this is going to be a string and we're going to return a pointer to the server like this and then I'm gonna return This Server with a listen address that we give it right and then we're going to attach some handles to it for example I'm gonna stick some things out of my dump uh handle get usage by ID or something right um which is going to be a w HTTP response writer response writer and an uh R which is going to be an HTTP request request and I'm not going to do anything in here I'm just going to save it and then I also make a start function for the server where we're gonna basically boot up our handlers and our uh you know actual HTTP service that's going to return an errors and then I say HTTP handle func slash usage or something I don't know hey you know the drill and then we're going to say s handle user get by ID then you're going to say HTTP now I'm going to return actually return HTTP listen and surf which is going to be listening to the S listen edit and this Handler you can just provide nil to it right that's it then in main we can easily uh say that the server is going to be an API right an API new server we're gonna pause in the lesson edit and then we're going to basically see a lock fatal service start just like that and what you also could do is basically let me undo this flagpart needs to be huge uh log fatal heat let's do fmt parental end service running on boards you could use actually let's do this and edit just like that right and then you could say go run main.go and it's going to use the default Port provided by the flag but we can also do the same thing once again and say dash dash lesson add and use something like 5000 or something right and it's now running on five thousand eight very simple all right the next thing the next thing you need to do is for example if you have types very important uh for example you have a user you're going to have an admin you're going to have a book or a to-do list or all your types that you're going to share across your program a lot of people calling this folder models but I don't like models it reminds me too much on an MVC pattern and that's not what we're gonna what I'm using uh but to be honest everything comes down at the same at the same principle um but what I'm doing I'm just call it types A package types where I basically provide all my requests and response types and all that stuff that I want to share across my program right so we're going to say new file user.go and uh we could say package types type users which is going to be stretch of course ID and name string whatever and you could do your Json stuff each for example Json ID small case let's do this this and this and this is going to be name right simple and of course uh something you can you can you can think about is how are you going to do your validation most of the time I do my validation in my API there's no need to make a validation folder there is no need for that most of the time you could actually do it here for example think validate usage I could say you use it a bull or something return false or true he's valid let's make it a valid one right and then you could just say types validate usage and if you don't like that then hey just uh make this function in your API or something that's what it is don't make it too complex that's for the types and you can see it coming everything for user is going to be here if you want to make an other type a book or something make a book.go simple as that all right the next thing is a data data layer right how do you add a data layer well it's very simple what I'm always doing is I make this uh storage package storage or package store or a just give it a name package storage and then um my bad getting sick I'm gonna call this storage .go and that's going to basically hold my interface I'm always making always making interface for your storage so it's going to be type storage it's going to be an interface and in this interface is basically going to hold all the functions your storage will need to implement I'm going to make it fairly simple and most of the case going to be get delete update and all that stuff I'm going to say get very simple it's going to actually what we could do here is um let's return it to usage let's do this and end and it's going to return a types usage just like that right that's why we have this separate types package so we can import it as a types user the next thing is the interface can be very small just one file with your storage if you really want to yeah if you really want to make it simple you could add all your storages in one file that's basically what I'm doing but if you want to make it clean because I'm a dirty boy but if you want to make it clean then you make a new file and you could say for example uh mongodb.gov you could say package uh storage and then you could say type DB or storage or something it's going to be a strict just like that and then it needs to implement that interface of course it's going to be I'm going to call it s from Storage it's going to be a pointer to this storage it's gonna be get uh ID and it's going to return types users use it yes just like that and then just say return and types users ID one name Foo right that's that that's taken care of actually I'm going to rename this um yeah let's call it whatever doesn't matter if you want to have a new folder a new storage very simple for testing for example because mongodb in this case of course it doesn't do a mongodb connection a I know but if you wanna what I'm a good practice is to make something in memory for your tests so what I'm always doing is a memory memory.go right then I say package storage once again type memory storage I'm trying to go fast if it's too fast let me know but uh hey don't want to make this video too long memory let me open up this Mongol thingy so I can copy this here paste it into the memory thing call it memory just like that types use it all good all good let's make a new let's make a Constructor new memory storage I'm gonna return a memory storage turn and memory storage that's fine delete this delete this close it actually cool so now our server why am I always opening this this garbage thing let's sweat is serve with heat boom so now our server of course if we have a server we need to have access to our database so how do we do that well you could say store and that's going to be a storage dot storage it's not going to be a storage memory store or storage mongodb store or postgres whatever you're going to use it's going to be this interface and we need to have a way to provide this storage to our server so we're going to have an other argument in our Constructor we're going to say store it's going to be a storage dot storage just like that and I'm going to say that the store is going to be this storage or storage boom and then what we could do in our handle get used by ID is the user is going to be as storage get for example 10 and then we could say um the problem is we don't have let's do this Json new encoders w encode use it something like that okay now in Main now in main we need to construct that's why I'm always telling that this minute go file is going to be your initialization file where you bootstrap the whole bank so we're going to say that the storage depending on what you want to use is going to be um for example this new memory store actually storage new memory storage and then you're going to pause in the store here boot up the service that's fine go run main.go it's going to be 3000 do we have Tinder client heat open new request it's going to be HTTP slash a local host three thousand well slash user or something not quite sure let's try boom you see and we have our user Heat id1 and the name is Foo right that's uh simple stuff but it gave you an ID of the of the of the structure it's very simple you have API for all your API handlers right if you want to make a new handle it's very simple it's a very simple you just copy this thing just like that boom and you're going to say a handle for example a delete user or something right and you do your stuff and then if you want to supply another Handler you're going to say users of course in this case we don't have access to delete you could use mux the mix router or something enable to route that stuff in a better way it's just for giving you some some examples right it's going to be handled get deleted ID something like that so you can see it coming you can add as much routes as you want and for example if you have some middleware it's very simple what I'm always doing okay the middleware boom package API or something and then Funk my middleware whatever you want to do with this right middleware there authentication if you want to have an authentication make a new file call it out or go or something and um do your authentication here very simple no need to create your out package where you're gonna do a gbt out and and uh or out and stuff and and make all these these folders just put everything inside of this API thing and just group it by file much easier you're gonna have less chance chances to run into circular dependencies another thing is uh very common is if you have utility functions for example you want to round stuff or you want to I don't know some simple utility functions that can come in handy across your whole application you make a util package or a common package or a utils package it doesn't matter new file and I'm go most of the time I just call this util.go package util and then if you say for example uh Funk rounds Val float64 it's going to return a float 64. let's let's call this function round to deck or something two decimals and I'm going to say return math round is going to be this Val times 100 divided by this guy and then if you need this submit in um where could we need this maybe a server or something and it's still opening the server it was going on with vs code and then you're going to say Val actually I'm going to do this so the compiler is not complaining about this variable we could say util around to deck something like that right you can see where it's coming and you can use it beautiful function across whole your application for testing uh very it's also a very common practice and it's basically an idiom in the whole Google community and that's if you want to test your Handler's heat don't make a package test or something for example the server what you could do is um just make a new file something and call This Server test boom and then you're going to say here package server no no yes no package API my bad and uh you could say funk test handle get users by ID or something which is going to have a t testing dot Mana need to be called testing the T or something right and if you want to know how to test handles I always already have videos about that um yeah so check that out if you want to know how to test these HTTP handlers so you can see and now you can scale your application as as as much as you want right you could you could add and actually to be honest also uh I did this once in uh in a time where I had a lot a lot of handlers is instead of attaching them to your server you can also attach them into a into into group them into different files right handles.go and all your handlers needs can be there for example it does not it's not because of server it's housing and the server.go that you cannot do this right you could do handlers package uh API and then you could say func s servers uh handle full responsibility how many times I wrote this thing is crazy a response writer or http.request something like that right of course we don't use this Handler and we could copy as much handle as we want and with full handle it brush Handler bus write all these things and then open up server here I said Candace this this stupid code thingy what's going on um so we could say handle a foo which is going to be s handle fool you see let's copy this heat handle but handlebar and copy one more for the bus it's going to be handle bus boom you see that's also an opportunity that's also a possibility uh if you want to do that if you want to split things out and if you have a lot of handlets you can group them by for admins for whatever you see where it's going you can be creative but there is no need to create all these folders that's the cause of all evil all right uh I think this approach is what I'm using over the years and it's it's never let me down I I yeah it's it's so simple everything for API is going to be here everything uh data related is going to be in storage all your types are going to housing types and then your utility functions uh are there it is what it is that's my way to go and I hopefully uh you guys had something about this video consider subscribing to my channel give me a thumbs up leave some questions in the comments and um jump into the Discord Community thanks for watching and I'm looking forward to see you in one of my live streams or future videos bye bye
Info
Channel: Anthony GG
Views: 45,107
Rating: undefined out of 5
Keywords: golang project structure, golang tutorial, golang, go programming language, go lang, go, golang for beginners, golang project, project structure in golang, golang tutorial for beginners, golang rest api, learn golang, go tutorial, go programming language tutorial for beginners, golang projects, go programming tutorial, golang programming, go programming language tutorial, go programming, go language, learn go
Id: EqniGcAijDI
Channel Id: undefined
Length: 20min 27sec (1227 seconds)
Published: Mon Dec 05 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.