 So hello, my name is Thomas. OK, and so I'm going to be talking today about microservices and a little bit about the Namco framework for implementing microservices in Python. So my name is Thomas Peterson. I'm an engineer at Thinkful, which is an online education platform for teaching people programming through mentorship. I've been working with Python for about three years now. I'm Ripley Affect with an A, most places, GitHub, Twitter, Play Pokemon Go. OK, so if you think about a web application, you typically think about it in three parts. And those parts are the client side, which is like what you're seeing in the browser, runs JavaScript, lots of frameworks like Angular and React that are really popular for that. Also data store layer, so something like Postgres, Mongo, something that stores your data across requests. And lastly, a back-end application, which is in Python. You can write this in Django, Flask. That's an app that runs on a server that handles stuff like routing, it handles HTTP requests. It'll usually have an API to expose some data and make the database calls, do the authentication. All of that stuff lives on the server in the same application. And that kind of application architecture is called a monolith. The monolith application is pretty well known. There are lots of frameworks that help you, like Rails is really a well-known one for Ruby. It has a lot of pros in that the code is really accessible. So you have access to the code. Wherever it is in the monolith, you can import it, run it, change it. There are also centralized models and usually a centralized data store. So a single Postgres server or something like that where all your requests go to, you have your model set up in their relational database or in documents in Mongo or something. And there's also a lower DevOps overhead. There's only a single app, you're deploying it. But it also has some cons. Scaling is a big one. So if you wanna scale one part of your monolithic application, you are going to have to scale the whole application and just create more instances of the application. Everything's fine. It's pretty easy to end up with this kind of, the term is spaghetti code, where you have a bunch of interleaved dependencies. It's kind of tangled and it's a little nerve-wracking to change anything in a monolith that's been around for a while because you don't always know what it's going to affect. And that can be tricky. So you test it and hope for the best. And you can have a long deploy cycle if there's a cube. Deploy is going out, a bunch of programmers working on the same code base, changing stuff that might change other things in the system. So there's this deploy cycle and you run your tests, your application goes up. Oh, this image is from an article written by Martin Fowler, who's kind of on authority on microservices. And it's an example of what a monolith looks like. You can see that these services inside the monolith are all inside of the same application and this is the monolith scaling. You just create more instances of the monolith. So recently a response to this has been this architecture that has kind of been coined as microservices. And microservices is an architectural style that has certain characteristics. Those characteristics are that services have small and isolated functionality. They're independently deployable, upgradeable, they have their own release cycles and they can be scaled independently. The functionality is usually exposed over some kind of network. Like you talk to a microservice over HTTP or RBC and you have a decentralized data store a lot of the time, which means that each of your microservices might have their own data store. They might connect to the same one, but it doesn't really matter. The data is distributed across many different parts of the system and that's different from having just a single Postgres server. And then the focus in microservice architecture is really on team independence and service independence and get to that a little bit later. And this is also from that same article. These are the services sort of isolated by themselves and you can see that they're scaled by themselves so you don't have to scale the entire application to scale a single service. So those are characteristics of microservice. That does not mean that microservices are inherently less complex. The complexity really just relocates to other parts of the system. And these are a few things that are more complex with microservices. You've got authentication problems, like speed of calls. If you're doing a local call, it's fast. If you're doing a remote call, it's just not as fast. Okay, so enough about microservices in general. We're gonna look at this particular framework for implementing microservices in Python. And that framework is called Namco. And Namco is two things but I like to think of it as three. The first is that it's a library of utilities that really lets you create these services and expose them over networks. The second is that it's a CLI command line interface for easily running and interacting with those services. So you have Namco Run, which runs your services. You also have Namco Shell, which allows you to easily interact with services over RPC or something. But it's also built in a way that encourages a particular style of thinking about your application logic. And that is that you think about your services as isolated from the rest of the system. And it encourages these practices through certain patterns that Namco uses, especially the use of dependency injection, which we'll see in a minute. So this is what a Namco service looks like. You can see that. So basically it has a name attribute. It needs a name attribute. It has potentially some dependencies, some dependency attributes, which we'll see in a little while. And then it has these methods on it that expose functionality of the service and the entry point decorators which are used to access or start that behavior from somewhere else. So say this is on a service, the services started and running somewhere. And we want to access it. Well, you can do that from the Namco Shell. And Namco Shell gives you this global N, which is an object that has a really nice way of interacting with Namco services. Specifically, it just makes it really easy to call things over RPC. And so here I have the service running and then to call it, I would say N.RPC.HelloWorldService, which is the name here. And then I call the particular method that I want. Say hello. And that'll print out Hello World. That'll go over the network and actually call that and return the return value of this service. This method on the service. And you might be thinking, how does that actually happen? How does Namco know where to go? How does it call a service that's running on maybe a separate computer somewhere? And the answer to that is it runs over RabbitMQ. RabbitMQ is a message broker that implements the advanced messaging Q protocol, AMQP. Which is a protocol for sending messages. And Namco really have to worry about Rabbit or think about Rabbit. Namco handles all of the interaction itself. So to look at some nomenclature that Namco uses, the term entry point is used to describe a way of exposing a method, usually by monitoring some external entity like the message Q we just talked about. Dependencies, which are ways of injecting sort of code that your service doesn't really know about or control. And that could be other services. It could be a connection to a database or something like that. And lastly a worker, which is a specific instance of a class of a service class. So services are classes and a worker is an instance of that class with the dependencies replaced with the result of this get dependency method that's implemented on the dependent. Okay, so I'm gonna take a look at some examples of Namco in action. And Namco has some built in extensions that it provides, which make it really nice to set up services of different kinds. The first one we're gonna look at is HTTP. It has a HTTP decorator, which you can use to decorate a method and expose that method over HTTP. It's influence get and post and multiple decorators can be placed in the same method that the exposure is built over Vercsoig, which is the way that Flask is built as well. If you've used Flask, you know what those response and the request objects look like and how they work. Cool, so let's give it a try. Here I have an example service that I'm exposing over HTTP. And it's gonna multiply two numbers that I pass into the route together. And you can see here's the entry point, HTTP get, it's on the multiply route and it takes in two URL params and it also has this request argument that you can pass in a third argument to be multiplied. It defaults to one so the result is just the value first and second in the default case. So this is the code for the service and then if we go over to here and just run Namco service one, see that Namco runs starts the service running and now we can go over here and go to localhost 8000, which is the default port and go to the multiply route, pass it in the arguments three and two and you see that the value is six. We can also go here, add a third, three and get the value 18 back. So that's just an HTTP service, simple HTTP service in action over get. Okay, so next one is RPC and RPC stands for remote procedure call. It's a really common thing in microservices because you want to be able to isolate that functionality in a particular service and then you want to access that functionality from somewhere that's remote. So RPC lets you do that. It lets you call a function from across the web. It's great. Namco implements RPC. It has its own implementation of RPC that's built on top of the message queue and it sort of abstracts that away from you so you don't have to think about it but what it's doing is sending one message and then it has a return queue that the result gets pushed onto and then the caller listens to that and gets the result back and handles it. There are three parts or three things that Namco gives you for dealing with RPC. The first is the RPC decorator and that exposes the particular method of the service over RPC. You also have RPC proxy which is an easy way of getting a dependency that you can call just like a normal method from a service and it'll go and do that over RPC and then you have cluster RPC proxy which allows you to call remote methods from a non-Namco client. Okay, so that's a little abstract. Let's see some code. So this is a simple RPC service. It's called Greeter service and it has this RPC decorator on top of the greet method and the greet method takes one parameter called name and it'll just return hello name. So, oh, there's one other step to this since last time I was just running an HTTP service but now I'm using the RPC capabilities of Namco. So if I try to run service two, I'll get a stack trace that says I can't connect and what that's looking for is a connection to the rabbit server. So I'm just gonna go over here and start a local rabbit MQ server. It's running on local host, guest, guest as the credentials and so now if I start up that service, I get that, it says started running Greeter service and now if I go to the Namco shell, it says that the broker here, it's connecting to rabbit at guest, guest, local host and I have this N global where I can call service. So we get that back and what that did was it sent the message to the Greeter service to ask for the result of that method and got that back and then it just printed it out to the console. So that's fine but what if we wanted to enhance this and we're gonna do that in with service three which is the expanded Greeter service. What this is doing is getting a dependency. It's saying get the Greeter service as a dependency and make it accessible from instances of this service. So this service in its greet method can actually call the Greeter service and get the result and use that in its method. So if I go over here and I start service three, expand a Greeter service greet and what that does is calls this service which then calls this service and uses the result from this service to send back a longer string. Which is again, printed to the console. Okay, so this is running inside of Namco Shell which gives you that global, it's really nice but in production we don't really have that ability and so say you have a Flask application and you want to call a remote service. You can use cluster RPC proxy and that just takes some configuration. It says where the message or where the broker is and I'm gonna call the expanded Greeter service from this client that isn't actually a micro service itself, it's just using our services. So that works, okay. Another important pattern in microservice architecture is publisher subscriber, also known as PubSub. Basically an event gets dispatched and there are zero to n subscribers to that event that then handle the payload that they get sent by then. And Namco gives you event dispatcher which is a special way of getting a dependency that gives you a dispatcher for dispatching a particular event, a particular payload and then another service can have an event handler decorator which subscribes to that event and then handles it however it wants. There's also event dispatcher which is again for non-Namco clients just like RPC cluster. Let's start, oh, let's see the code first. So service four is an event dispatcher and it when called over RPC it's going to dispatch my event with the payload that it gets handed. And so that event sort of goes off into space and over here in service five we have two services that are both listening for my event, my event events from the my event publisher service. So over here. So if we start up service four and service five, and then go show.pc.publish. So you can see over here that these services receive this event, the event got sent or this service was called sent an event, these two services picked it up. And you can see that this class is up here but it doesn't really matter what order they're in. They'll get it at different times. So if I run this multiple times, you can see that they'll receive the event in different orders. So the last entry point that I wanted to talk about is timer, it's really simple one. It just does one thing over and over and over and over again forever. And you set that with the timer entry point decorator over here. So over here's a ping service that when started is just gonna run ping every second forever. So it's running, it's just printing out every second. Cool, so now you want to move everything to microservices and that's great because my demos were so amazing. Well, you probably shouldn't really Yeah, microservices are really, really complicated and they're useful in a lot of ways but they take time to get right, they take time to understand and you have to get into this particular way of thinking to understand how your microservices are structured and how your application should be structured around them. So they're a really new concept. I mean, the concepts behind microservices have been around for a long time there, like Unix. But this architecture can also lead to really, really complicated systems when implemented incorrectly. So my recommendation for you is to try this at home. You should play around, see what you can do with Namco services, play around with different types, see how they interact and when it's time to implement something, work or at home, a side project or whatever and you want to just isolate some functionality or you want to take a library and move it away. If you have a library, you can't upgrade and you want to upgrade it but you can't in your monolith so you want to put it in a microservice or something like that. Or if you just want to play around with a new data store, I like RethinkDB and you can do that with a microservice without sort of messing with the data model in your model application. And so that's all I got. This code is all available at my GitHub handle Ripley effect slash Namco examples. And I'm out of time, but there's any burning questions? There are companies out there that sort of success stories for microservices. There are probably also a lot of, how does it compare to something like Flask? Microservices are really not meant for human consumption. They're meant for computers to talk to each other. So an app in Flask is a lot more human readable. It's a lot easier to jump in as a developer and sort of understand what's going on but microservices is a pattern that you create when you want a bunch of computers to talk to each other. The services are discoverable, they're isolated, they're not really super human friendly but they do help once you get into the method of thinking about these services is like isolated pieces of logic really helps you sort of concentrate on doing just one thing, which is really nice. I mean an API, how does an API in microservices work? Yeah, yeah. APIs, you would probably do something, sort of a saying is smart end points and dumb pipes, which is like, you have some logic that sort of collects the information you need in the endpoint that exposes your API and then you call the services that you need through some of the like, non-acid. I typically write all my APIs in Flask. I really enjoy it. I would use this just like making HTTP requests from Flask to a microservice for maybe some data. Sorry, I'm sorry. It's okay. Oh yeah, the problem of authentication is a huge one with microservices. It's Harry, we can talk later. An okay solution is Json Web Tokens, JWT. You can sort of pass through to microservices and then have some special decorator that implements your authentication and authorization for that service. Okay, I gotta get out of here, I guess, yeah.