When you're thinking about putting together embedded systems, that communicate whether with the Cloud or with each other, two things that are particularly important to those architectures are APIs and microservices. We'll talk about both of these, we'll look at using APIs and embedded development. We'll talk about some of the more popular API approaches, and then we'll talk about how microservice architecture impacts system design and the use of APIs. Why do we care about APIs for embedded interfaces? Well in practice, you could create an embedded device that doesn't actually have a user interface or it may be that not everything that the device provides is available through its user interface. Whether it's configuring, diagnosing, providing some input, gathering some output, you may have to connect to that device from some program or through web-based API. You want to have some defined interface that you'll use when you have to talk to this device. In an embedded device, there's already one layer that's usually present. The HAL abstraction layer, where the hardware that the device depends on is abstracted away from the use by the RTO's or other middleware. We put that there so that, that HAL layer can let us change elements of the hardware without necessarily impacting what's above. An API is analogous to this, the API might sit between your application code and the device are RTO's and middleware in that case, again, depending on what changes on either side of that API, the API could evolve to provide additional or modified functions as time goes by. Usually, APIs are found in two primary forms, RPC-based or REST-based. We'll talk a bit about both. But really, REST-based APIs are probably the ones we see most of the time for these type of systems. RPC-based API generally just uses a single universal interface point to make its connections through posting commands. Typical examples of these would be things like XML and SOAP. These were very common protocols, or early on in setting up communicating systems, but these days, they're used less in favor of the REST-based protocols. The nice part about RPC though, is you can pass a structured request through a standard approach. You can expect a standard structured format back. It can make for a very simple single point communication. There's only one endpoint on either side to concern yourself about, that will supply all of your different operations. It's very structured, very predictable, but it's not as interactive as most RESTful APIs. It's probable that you won't be able to tell what resources are available unless someone has done a really good job of the API design. That's something that maybe more built into a REST API and it doesn't use the standard REST verb set or response codes that you might be used to. Again, it could be a very custom interface, but it's more of a one size fits all, and it may not work for your application. A REST-based API, again, much more common, leverages the standard set of HTTP functionality, a standard set of verbs most of these are familiar with that have done any web coating, PUT, GET, POST, DELETE, etc. Clients can specify often times at a RESTful API, how they're going to be providing information. Are they going to use XML or they're going to use JSON, etc? Linking between resources can be used to show relationships between elements inside the API, messages. REST APIs again, can provide information about the interface if you're looking to understand what resources are there. There's a maturity model for APIs called the Richardson Maturity Model. That goes from very plain XML format into providing different resources using the different HTTP verbs and extending the hypermedia links within your messages. A good RESTful API will use unique interface points for services and the item is exposed by those services. It'll use the full spectrum of verbs to provide for the operations that you're going to need when you're working on those resources. Again, being able to get to a RESTful API and ask for resource information is one way that a consumer of that API could determine what they'll be using and what they need to do to move into the API further for more control or for more information. There's a lot of questions you need to ask yourself as you're putting an API together. REST doesn't really dictate formats so you have to consider again what representation formats you'll use inside your API strings, XAML, JSON, et cetera. REST also doesn't dictate specific error codes although most people will use the standard HTTP codes like a 200 for a good communication or a 404 if something is not found or whatever is appropriate. Which HTTP methods will be available for a given resource and how you respond to failed requests is something you have to consider. Then if you get into any serious communication, you have to start thinking about authentication and credentialing and that opens up an entire other set of tools and functionality that you're going to have to consider as you're pulling your system together. You certainly need to think about how you're going to document the API, is it going to become a full-fledged SDK or software development kit that people are going to use to put together their systems. If that's so, not only do you have to define the API, you have to provide usage examples and tutorials. You're probably going to want to validate that documentation with someone that's actually trying to use the system to make sure that the user experience is what you'd expect. Once you publish an API, you're responsible for its stability and consistency. If I've written code to version one of your API and you you update to a version two, you really have to consider how people using the version one API are going to be able to function. Can you provide both?, can you provide a way for changes to be dealt with?, how do you document the differences in versions?, how do you maintain changes and still let older software run?. These are all concerns. Your API ideally should be flexible, you want to be able to provide for different formats of input and output and you definitely want to make sure that the use of those, the combination with versioning is all a part of how you set up your API. Security is an issue with APIs. If you do something that again gets publicly put out on the Internet, you're certainly going to see traffic pinging that interface, trying to get in, trying to make connections that you didn't expect. This is where things like SSL, OAuth2, token-based authentication, all become part of what you need to do. You may have to eventually be able to whitelist or blacklist certain connections or functions, verify and validate resource connections. All these things have to be considered. It's a blend of trying to make something that's easy to adopt. You'd like people to be able to program to your API in a way that you would expect but on the security side, you've got to have enough complexity there to keep the authentication and the security in place for those transactions. There's a balance here and it's always a tough one. I highly recommend using a tool for API design. One that I've had some experience with in the past is swagger. Swagger uses a specification called the open API. Essentially you're going to define using a JSON based API, your REST API patterns and then be able to use that API to generate both client and server side connections. It'll create stubs for the server and SDKs for the clients which can make it really easy to create the documentation, make examples, et cetera. Swagger is a super tool for this kind of API design. There are other alternatives out there, a common one is called RAML, RESTful API modeling language. You can take a look at that one too, swagger has both open source in a commercial version, the open source tools are very good. Other tools for API design. Just listing a few here that you can think about. If you're on AWS, you can certainly use the API Gateway there. It's part of designing an API on Amazon that connects different elements together. You can use load testers, testing tools, mock applications to create API stubs. All these things are available to you. Again, I think Swagger is a particularly good place to start and it's compatible with some of the Cloud-based API and tools. Let's talk about microservices a little bit. Microservices, a relatively new concept in architecture, really talks about creating independent, deployable components that handle the interoperability of those components through messaging. Again, APIs are a key to this because the microservices are dependent on the API to get and send messages. A microservices architecture uses these small independent pieces to build up a system. The idea here is that you're really trying to make something where the individual elements are easily replaceable. This is targeted at bigger systems, Cloud-based systems, and it's drawn from service-oriented architectures. Certainly also, fits well into DevOps, automated and continuous deployment and Agile development of these elements since they can be replaced, whenever they're updated. If you look at a microservice, they're usually very small, very cohesive. They work with messaging. They have a single set of functions that they're providing that will work autonomously. It's decentralized. It's not part of a bigger piece of software. It's easy to build it and release it and get it back into your system when you make changes. The goal with the microservices is to try to balance the speed, the safety, and the scaling of your applications. The design process really, you want to look at what the goals and the principles are for the individual elements of your microservices. Sketch them out, iterate through their design, make an implementation, see how it works, and then repeat that process. A microservice should be very independent and deployable, so if they have any dependencies it should be part of the service and clearly noted. The key here to make these things talk to each other again, is the API and the messaging that's used. What you'll see is this is really a method for moving from large monolithic applications into decomposed sets of microservices that can be easily brought out in online and updated. Oftentimes there's an in-between pragmatic implementation if you've got pieces that don't translate well. But generally speaking, microservices are becoming more and more away to put together the support behind a device network. For microservices, the APIs have to be standard. The microservices themselves are probably dependent on some kind of a container or container management system, Docker, Kubernetes. You have to be able to discover their services, understand how routing works. Security, of course, between all of these elements is a key and being able to monitor and observe the system as it's deployed to make sure it's working the way you expect will be important. AWS provides, of course, the serverless elements of Lambda in order to make connections between different parts of your system. There's a good example here of creating a serverless microservice that uses the AWS API Gateway, Lambda, and the AWS Dynamo DB for storing data. Lambda itself can be used to create an endpoint. Security can get setup for the microservice. An API can be published and then data can be moved in and out of an AWS Dynamo DB table. We do a lot of this productivity in the examples for the class. But you certainly might want to take a look at this link and just walk through how these pieces talk to each other in a typical microservice.