As we start out in our demo environment,
I want to start by saying that a lot of the application has changed.
Now, normally,
I would encourage you to go to the exercise files so you can
follow along and see all of the code in detail.
And I would definitely encourage you to do that.
But I am going to take a second just to review the architecture here
because there is so much that's different here that I don't want you to
get lost as we're building through the demo.
So, the first place that you'll notice our big change is our main function.
Now, let me step back and talk about what we're doing at a very high level.
So, normally with a microservice architecture,
you would have multiple applications, and you'd have some sort
of a service discovery mechanism so that the microservices can
find and talk to one another.
Well, since we're in a demonstration environment,
I'm skipping that step, and I'm simply going to have one application that
starts off three web services, and that's going to be our ProductService
that we've worked with earlier in the course,
our CustomerService that we worked with even earlier in the course, and a
ShoppingCartService that I'm introducing in this demonstration,
that's going to take advantage of both the CustomerService and the
ProductService to register items in a customer's shopping cart.
So the way that I've got this working in a single application
is notice right here in line 17 through 19,
I've got three functions that are creating the Service instances.
Let's go down to the first one,
createCustomerService, and find that function, and
we see that that's right here.
Now,
this function is almost exactly identical to the main
function that we had in our very first demos in this course.
We're opening that customers CSV file,
we're reading the customers in, and then we're registering a handler that's
going to return all of the customers back out in a JSON format.
And then we also have another handler that's using regular
expressions and parametric routing to return a single
customer that's being requested.
Now,
one of the primary differences between this implementation and what we
saw earlier in this course is notice that the HandleFunc function is
not actually coming from the HTTP package.
It's coming from this mux object.
Let me scroll up and show you where that mux object is coming from,
and that's right here on line 119. Because we're creating multiple
servers that each need their own internal routing, we can't use the
default serve mux. Because if we did,
they'd all have the same routing because they'd all be using the same router.
So we're using this NewServeMux to construct a router that we can
then assign on to the servers that we're creating.
So, if I scroll down a little bit further into the
constructor for the service itself,
notice on line 166 here that I'm adding a Handler field.
Now, we haven't done that before because we used the default serve mux before.
But now, I want to specify a specific handler.
Now, this has nothing to do with middleware.
This is just the architecture of the demo right now.
So, in short, I'm creating a custom server,
creating a custom router for it, and then registering my
handlers with that custom router. And then return that
server back up in my main function.
And I do that three times, once for the CustomerService,
once for the ProductService, and once for the ShoppingCartService.
Then I've got these three go routines on line 21, 25, and 29.
Those are just starting the services up so they start listening. And then
I've got my Shutdown functions on line 33 through 38.
So, when I do want to bring down the entire service,
the application gracefully shuts down each one of those services
in turn, and then it terminates execution.
So the ProductService and the CustomerService are working the
same as what we've seen earlier in the course,
our application is just starting those up. Now, over here in cart.go,
I've got the ShoppingCartService. And this is a very simple service.
We're simply defining a type called Cart that has its own ID.
And then it's got the CustomerID for the specific shopping cart we're
using, and then a slice of ProductIDs because the customer can register
multiple products in their shopping cart.
Then I've got the createShoppingCartService that has the same
function as the createService that we saw before.
It's just creating the ShoppingCartService.
And then I do have the Handler defined as a separate function. Notice on line
22, I'm using HandleFunc and registering the cartsHandler.
Well,
that's down here on line 33, and we're registering on
one endpoint, two http methods.
So, on a Get request,
we're going to return all of the carts. And then on a Post request,
we're interpreting that as a request to add a new
shopping cart to the ShoppingCartService.
So, to show you how this all works,
let's go over to the main.go file, and let's just send
a quick request to the CartService.
Now,
this isn't going to do anything with the
ProductService or the CustomerService yet.
We'll get to that in a little while. But we're just going to use a
Get request here to http://localhost:5000/carts.
That's the endpoint that I've registered. And, of course,
that returns a response object and an error, so we'll
add some quick error handling here.
Hopefully, we don't get an error.
Now, I do want to give enough time for the services to get started.
So let's go ahead and add a Sleep call here, just so we make sure that
those are active and listening on their TCP ports.
So we'll just give it a Second delay. And then, just to
keep things as simple as possible,
I'm going to print out the entire response body.
So we'll get that response body by using the ReadAll function from
the io package. And we'll read the responses Body, and then we'll
simply print that out. Convert that to a string so it doesn't just
show up as a random series of bytes.
And we do have to add some error checking here, so
let's go ahead and do that as well.
Matter of fact, let me change these from Prints to Fatal.
Okay, so now everything should be set.
So again, we're not expecting anything too miraculous here.
We're just going to send a request to the carts.
We should get an empty slice back, and then we'll
print that empty slice back out.
Let's go ahead and open up a terminal here, build the application and run it.
Give it a second, and we do see that we get that response back
out, and it is as expected, an empty slice.
So that covers where our services are at right now.
Now, in the next demonstration,
we're actually going to start building up the middleware.
So, the middleware we're going to start with is a global middleware,
where we're going to add some logging functionality. We'll take a look at how to do that next.