Building Hexagonal Microservices with Go - Part Three
Key Takeaways
Building a URL shortener service using hexagonal microservice architecture in Go, creating a REST API and handling requests and responses, with tools like Go, Redis, and message pack library
Full Transcript
hey guys my name is tensor welcome back to the hexagonal micro service tutorial series in the last video we set up our serializers and our repository and in this video we'll go ahead and finish off our microservice by setting up our API let's go ahead and create the API layer using an HTTP library and I'm going to use this library here called goichi and this is kind of similar to the guerilla moxa library except it's literally just middleware and a router so it allows us to generate a bunch of routes and then also put some middleware on the routes so inside of a folder called API and inside of a file called HTTP go I'm going to make some imports here so IO IO util log net HTTP then I'm gonna bring goichi and then our errors package and then I'm gonna bring in our serialization packages so the serializer JSON and serialized inner message pack and then I'm also going to bring in our domain logic which is just our shortener library now for simplicity sake I'm just gonna create a redirect handler interface and this interface is just going to help us create the methods that we want for our HTTP lair and along with the interface I'll create a handler struck which will contain the redirect service which is just our enough service let's go ahead and create a function here called new handler which will take in our redirect service and then pass back a redirect Handler and of course this is the redirect handler interface not the handler struct but we're going to implement this interface on our handle or struct so we can just pass back a handler struct with our redirect service inside of it then because we have two serialization types we need to set up the response headers so when we send back a response if we're using JSON then we want to send back a response header that says that we're using JSON and if we're using message pack then we need to tell the browser or the client whatever is reading this we're using message pack we'll create a function here called setup response this will take in the response writer the content type string the body which will be a slice of bytes and then the status code and we can go ahead and call W dot header dot set content type and then pass in the content type and then we can call W dot right header passing the status code and then call W dot right and then pass in the body and if we get back an error then we can just log println error and again because we're using two serialization types we want to create a function which will make it easier for us to deal with the different content types so we can go ahead here and just take in the content type string and then pass back our redirect serializer interface and we'll just say if content type equals application X message pack then we'll pass back a message pack redirect type otherwise we'll pass back a JSON redirect type alright so now let's go ahead and create our get and post methods so get is just going to allow the user to call and get requests and then post is going to allow the user to call a post request the get request is just going to redirect to the URL that's being stored inside of the database and then the post request is going to allow us to create a code which we can use to then redirect to that URL remember the code is coming in through the path so we can get it from GDL per am and we can look for code and then this will give us the code then we can go ahead and call handler redirect service find and pass in our code and if we get back an error then we want to check to see if the errors cause was shortener error redirect not found and if it was then we can pass back that we got an HTTP status text of status not found otherwise we'll pass back the error and we'll pass back a status internal server error then finally if we didn't get an error then we'll go ahead and just call HTTP redirect and we'll then pass in our HTTP response writer and our HTTP request then we'll pass in the redirect URL and then we'll call HTTP status moved permanently to move along to the redirect URL now let's deal with post and with post we're going to be working with either JSON or our message pack message type so we can go ahead and get the content type from our header request header get content type then we want to go ahead and get our request body and convert it into a slice of bytes so we can just use io util read all on our dot body if we get back an error then we want to pass back HTTP status internal server error otherwise we'll continue and we'll call handler dot serializer with our content type and then we want to decode the request body bytes into the proper message type again we'll go ahead and handle the error so if we have an error we'll pass back a status internal server error then we want to go ahead and call on a redirect service and call the store function so that we can put our redirect into our database and again we want to handle these errors so if we have an error and if the error is shortener error redirect invalid then we can pass back an HTTP status battery quest otherwise we'll pass back a status internal server error then finally because we want to display a JSON representation of our new redirect with the created and the code inside of it back to the user from this post call we can go ahead and call H dot serializer with the content type so if it's jae-sung we'll serialize it into JSON and if it's a message pack well serialize it in the message pack and then we'll call in code on our redirect and this will give us back another slice of bytes which will be our new response body and again we want to handle an error so this will be a status internal server error again and if we don't an error then we can go ahead and just call setup response pass in the writer the content type the response body and then HTTP status created and this will give us back the JSON or the message pack message so that we know what the new code is so that we can call to our redirect already so now we're finished our API we're finished our repositories were finished our serializers and of course we're finished our service we can go ahead and come into our package main and tie everything together so that we can run this micro service now for our application we're going to use environment variables rather than command line flags to allow us to set up our port and to allow us to set up what type of database we wanted to use for our micro service so first let's set up the port so I'm going to create here a function called HTTP port which will pass back a string and by default we'll have a port of 8,000 and we'll check to see if the port environment variable has been set and if it has been set then we'll take that and put it into our port and then we'll pass the port back and we'll format it by putting it inside of a string just like with the port we want to make it so that we can choose the proper database so I'll create a function here called choose repo and this will pass back a redirect repository and what we'll do is we'll just check to see if we have an environment variable called URL DB and we'll check to see whether or not that is Redis or so if it's Redis then we want to look for an environment variable called Redis URL and if we have Redis URL then we can go ahead and call our our new Redis repository with that Redis URL inside of it and then return the repo back and with is going to need three different environment variables URL MongoDB and then now and again we can use these three different values inside of our new repository to create a new client and then we can return that repo and then finally if none of these apply then we'll just return nil now let's go ahead and set up our main function so first we'll call choose repo to see which repo we're going to use then we can set up the service by calling shortener renew redirect service and putting in our repo and then we can set up our handler by passing our service in so H dot new Handler and then passing in service then we can spin up our router by calling cheat new router and we can add a bunch of middleware so let's go ahead and add the request ID the real IP the logger and the recovery all of these middlewares help us see where our requests are coming from and what is happening with our service then we can set up our two routes so we want to have a get method on our code route so this is just on route code and then we have a post method on the route and we can connect these to handler get and handler dot post then finally we want to create a channel of errors with a buffer of two and create two go routines one we'll go ahead and run our server by using listen and serve and calling our HTTP port to put the port in and then putting in our router which is our and then the other one we'll listen for any kind of exit and notification that we create on the keyboard so if we hit like control C or something like that then it will get that value and it will then notify the system that it wants to quit and then finally we want to drain our errors channel so we can go ahead and just print that out and we can just say terminated with a string and all that stuff all right so now let's go into our terminal and we'll start with Redis as our database and we want to set up the Redis URL and I'm just going to use the default Redis URL which is just localhost six three seven nine and we can go ahead and run our application you can see it comes back and says that we're listening on port 8000 if I open up postman I can go ahead and call a post on our localhost 8080 R and I'm just going to pass in the URL and I've got a URL that is connected to my github tab repositories and if this succeeds you can see here that we get back our code we get back the URL and then we get back the created at timestamp we can now open up Mozilla and pass in localhost 8004 and it should redirect to that github URL and as you can see it did in fact do that so here we are on my repositories page now if we come back into our command line you can see here that we did have two different requests that happened and it shows us a bunch of information about each of these requests so we had a post request and then we had a get request and both of these succeeded now let's go ahead and see if MongoDB works so we want to set up the URL and I'm just gonna pass in the URL to the shortener database I'm gonna set up the timeout now I'm gonna put in 30 seconds and then we'll set up the database name which is just shortener and then we'll set the database type to and now I can go back into postman put in a new URL and then pass it in and get a new code so here I put in the github for goichi and we get back this code and this should then redirect to that github page and it does indeed work but this time our database is now being stored inside of MongoDB unfortunately there's no way for us to test the message pack protocol using something like postman or our browser so we're gonna have to go ahead and create a tool to test it out I'll create a new folder here called tool and inside of it I'm going to create a file called message pack go inside of this folder we want to create a tool that we can run at the same time that we're running our micro service which will allow us to input some data take that data serialize it into message pack then post it to our API wait for the response and then print it to our console so first let's bring in some imports we're gonna need all of these libraries the two notable ones will be the message pack library and then of course our service and the only reason why I'm bringing in our services so that we can use the redirect struct to organize our data I'm going to go and steal this function from our main deco file because this is the way that we set up the port inside of our application and we can just reuse it in this case now we could very easily make it so that we can input data into this tool using our command line but I'm just going to hard code some data in here and have it be sent into our API as a message pack format so first I want to create our address so it's just localhost plus our port and we can just call HTTP port and then I'm going to go ahead and create a redirect and then put a URL inside of that redirect and here's the URL that we're going to use and we're going to serialize to message pack let's go ahead and actually do that so we just call message pack Marshal and then pass in our redirect and then this will give us back a body which is just a slice of bytes with the representation of our data structure and now that we have the body we can go ahead and just call HTTP POST on our address with a content type of application X message pack and we want to take the body and put it inside of a buffer and of course we'll handle the error and then we also want to defer closing the response body to read the response we'll go ahead and use IO you to read all on our response body and this will give us back an error and our body and we can go ahead and of course long the error if we have it otherwise we can take the body call message pack on Marshall on it and unmarshal it back into a redirect and then print it out to our console let's just go ahead and rerun our microservice and I'm going to run it with Redis and then we can go ahead and run our little tool here and you can see that we get back our code the URL and then the timestamp and of course if we come over to our API we can see that a post request was made on localhost 8080 'td alright guys well I hope you enjoyed this tutorial if you did feel free to like and subscribe if you have any questions or comments feel free to leave them in the box below and if you dislike this video then by all means download it as much as you like if you want to see more videos like this feel free to click the notification bell have a good night
Original Description
#tensorprogramming #golang #microservices
In this series, we take a look at the hexagonal microservice architecture in go by building a simple URL shortener service. In this video we finish the application by creating a REST API.
Source Code: https://github.com/tensor-programming/hex-microservice/tree/part-3
Good Programming Laptops:
Lenovo ThinkPad E570: https://amzn.to/2TFEiVG
Dell XPS15: https://amzn.to/2RxyavP
Cloudways Web App Hosting: https://www.cloudways.com/en/?id=507366
Support the Channel and Join Patreon:
Patreon: https://www.patreon.com/tensor_programming
Dontate:
ETH: 0x03247265dd5242605bD2FA3c40fb3b70d9e3D685
Cardano: addr1q9auccwrr9ws8qdyv45f4qwsx76pfmld4zapks89sakq94ay0xmle73y0r8ruwd0zslls4eglf98lghru7ywv56cedysk7ftjt
Check out our Twitter: https://twitter.com/TensorProgram
Check out our Facebook: https://www.facebook.com/Tensor-Programming-1197847143611799/
Check out our Steemit: https://steemit.com/@tensor
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Tensor Programming · Tensor Programming · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
NodeJs, Text editors and IDEs
Tensor Programming
Vanilla JS todo App
Tensor Programming
Elm Tutorial part 1
Tensor Programming
Elm Lang Tutorial, Part 2
Tensor Programming
Elm Tutorial Part 3
Tensor Programming
Elm Tutorial Part 4 -- Analog Clock App
Tensor Programming
Elm Tutorial part 5 -- Snake Game
Tensor Programming
Elm Tutorial part 6 -- Calculator
Tensor Programming
Go Tutorial part 1 -- Hello World and Static File Server
Tensor Programming
Go Tutorial part 2 -- Web Crawler
Tensor Programming
Go Tutorial Part 3 (Web App part 1)
Tensor Programming
Go tutorial Part 4 (Web tutorial part 2) - Using templates
Tensor Programming
Go tutorial part 5 (web app part 3)
Tensor Programming
Go tutorial part 6 (webapp part 4)
Tensor Programming
Go tutorial part 7 (web app part 5)
Tensor Programming
Go tutorial part 8 (Web app part 6)
Tensor Programming
Go tutorial Part 9 (web tutorial part 7)
Tensor Programming
Go tutorial Part 10 (web app part 8)
Tensor Programming
Go tutorial Part 11 (Web app Part 9)
Tensor Programming
Go Tutorial Part 12 (Web app Part 10)
Tensor Programming
Go Tutorial Part 13 (Web app Part 11)
Tensor Programming
Looking at Elm 0.18
Tensor Programming
Go tutorial Part 14 (Web tutorial part 12)
Tensor Programming
Go tutorial Part 15 (Web tutorial part 13)
Tensor Programming
Go tutorial part 16 (web app part 14)
Tensor Programming
Elm Tutorial Part 7 (SPA part 1)
Tensor Programming
Elm Tutorial Part 8 (SPA Part 2)
Tensor Programming
Electron Elm Tutorial
Tensor Programming
Go tutorial part 17 (web app part 15)
Tensor Programming
Up and Coming Programming Languages and Technologies for 2017
Tensor Programming
elixir tutorial part 1
Tensor Programming
elixir tutorial part 2
Tensor Programming
Elixir tutorial Part 3 (GenServer and Supervisor)
Tensor Programming
Elixir Tutorial Part 4 (GenStage)
Tensor Programming
Elixir Tutorial Part 5 (Plug and Cowboy)
Tensor Programming
Phoenix Framework Tutorial Part 1 (elixir part 6)
Tensor Programming
Phoenix Framework Tutorial Part 2 (elixir part 7)
Tensor Programming
Phoenix Framework Tutorial Part 3 (elixir part 8)
Tensor Programming
A Intro to Clojure and Clojure Syntax
Tensor Programming
An Update about the channel
Tensor Programming
Intro to Rustlang (Setup and Primitives)
Tensor Programming
Intro to Rustlang (Strings, Tuples, Arrays, Slices and Pretty Printing)
Tensor Programming
Intro to Rustlang (Ownership and Borrowing)
Tensor Programming
Intro to Rustlang (Structs, Methods, Functions, Related Functions and the Display/Debug Traits)
Tensor Programming
Intro to Rustlang (Control Flow, Conditionals and Pattern Matching)
Tensor Programming
Intro to RustLang (Enums and Options)
Tensor Programming
Intro to Rustlang (Vectors, HashMaps, Casting, If-Let, While-Let, and the Result Enum)
Tensor Programming
Rustlang Project: Snake Game
Tensor Programming
Intro to Rustlang (Traits and Generic Types)
Tensor Programming
Intro to Rust-lang (Closures, the Box Pointer and Iterators)
Tensor Programming
Intro to Rust-lang (Modules and Lifetimes)
Tensor Programming
Intro to Rust-lang (Macros and Metaprogramming)
Tensor Programming
Intro to Rust-lang (Error Handling)
Tensor Programming
Intro to Rust-lang (Concurrency, Threads, Channels, Mutex and Arc)
Tensor Programming
Intro to Rust-lang (Tests, Attributes, Configuration and Conditional compilation)
Tensor Programming
Rustlang Project: Port Sniffer CLI
Tensor Programming
Rustlang Project: Chat Application
Tensor Programming
Rustlang Project: CLI Toy Blockchain
Tensor Programming
Intro to Rust-lang (Setting up a Development Environment)
Tensor Programming
Intro to Rust-lang (Building a Web API with Iron)
Tensor Programming
More on: Distributed Systems
View skill →
🎓
Tutor Explanation
DeepCamp AI