github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/docs/blog/_posts/2020-11-05-micro-v3-aka-m3o.md (about) 1 --- 2 layout: post 3 author: Asim Aslam 4 title: "Micro 3.0 (M3O) is a platform for cloud native development" 5 date: 2020-11-05 10:00:00 6 --- 7 8 This is the official announcement for the release of Micro 3.0 better known as M3O - a platform for cloud native development. 9 Our 3.0 release is a major refactor and consolidation of the existing tooling into something that addresses the entire workflow 10 of build, run, manage and consume all from the developers perspective. 11 12 Read on to learn more or go straight to the [latest release](https://github.com/tickoalcantara12/micro/releases/latest). 13 Head to [m3o.com](https://m3o.com) for the hosted offering. 14 15 ## Overview 16 17 Micro focuses on developer productivity for the backend. It's clear that the Cloud has become infinitely more complex 18 over the past few years. Micro attempts to create order out of that chaos by distilling it all down to a handful of 19 primitives for distributed systems development. 20 21 Why should you care? If you're reading this you've no doubt encountered the tedious nature of infrastructure management, 22 wrangling a kubernetes cluster on AWS or the thousands of things you need to do to cobble together a platform before 23 starting to build a product. We think we've nailed the solution for that just as Android did for Mobile. Keep reading 24 if you want to find out more. 25 26 ## Quick Flashback 27 28 Micro started out as a [toolkit for microservices](/blog/2016/03/20/micro.html) development, 29 incorporating an api gateway, web dashboard and cli to interact with services built using a Go RPC framework. 30 Back then it felt like getting anyone to buy into PaaS again was going to be a losing battle. So we chose 31 to write single purpose tools around an RPC framework thinking it might allow people to adopt it piece by piece 32 until they saw the need for a platform. It was really straight forward right until it wasn't. 33 34 There was a simple Go framework plus some surrounding 35 components to query and interact with them, but like any long lived project, the complexity grew as we 36 tried to solve for that platform experience that just couldn't be done with a swiss army knife. The repo 37 exploded with a number of independent libraries. To the creator its obvious what these are all for but to 38 the user there is nothing but cognitive overload. 39 40 In 2019 we went through a [consolidation](/blog/2019/06/10/the-great-consolidation.html) of all those libraries 41 which helped tremendously but there was still always one outstanding question. What's the difference between 42 [micro](https://github.com/tickoalcantara12/micro) and [go-micro](https://github.com/micro/go-micro)? It's a good 43 question and one we've covered before. We saw go-micro as a framework and micro as a toolkit but these 44 words were basically empty and meaningless because multiple projects working in coordination really need a 45 crisp story that makes sense and we didn't have one. 46 47 In 2020 we're looking to rectify that but let's first let's talk about platforms. 48 49 ## PaaS in 2020 50 51 5 years ago the world exploded with a proliferation of "cloud native" tooling as containers and 52 container orchestration took centre stage. More specifically, Docker and Kubernetes redefined the 53 technology landscape along with a more conscious move towards building software in the cloud. 54 55 Micro took a forward looking view even as far back as 2015. It was clear distributed systems and cloud native 56 was going to become the dominant model for backend services development over the coming years but, what wasn't clear 57 is just how long we'd spend wrangling all sorts tools like docker, kubernetes, grpc, istio and everything else. 58 It felt like we were rebuilding the stack and weren't really ready to talk about development aspects of it all. 59 60 In fact at that time, people mostly wanted to kick the tyres on all these tools and piece something together. 61 Running kubernetes yourself became all the rage and even using service mesh as the holy grail for solving 62 all your distributed systems problems. Many of us have come to realise while all of this tech is fun 63 it's not actually solving development problems. 64 65 We've gotten to the point of managed kubernetes and even things like Google Cloud Run or DigitalOcean App 66 Platform, but none of these things are helping with a development model for a cloud native era. Our 67 frustrations with the existing developer experience have grown and Micro felt like something that 68 could solve for all that, but only if we took a drastic step to overhaul it. 69 70 We think PaaS 3.0 is not just about running your container or even your source code but something that 71 encapsulates the entire developer experience including a model for writing code for the cloud. Based on that 72 Micro 3.0 aka M3O is a platform for cloud native development. 73 74 ## What even is Cloud Native? 75 76 What is cloud native? What does it mean to build for the cloud? What is a cloud service? 77 78 Cloud native is basically a descriptive term for something that was built to run in the cloud. That's it. It's not 79 magic, it might sound like a buzzword, but the reality is it simply means, that piece of software was built 80 to run in the cloud. How does that differ from the way we used to build before? Well the idea behind the cloud 81 is that its ephemeral, scalable and everything can be accessed via an API. 82 83 Our expectation for services running in the cloud is that they're mostly stateless, leveraging external services 84 for the persistence, that they are identified by name rather than IP address and they themselves provide an 85 API that can be consumed by multiple clients such as web, mobile and cli or other services. 86 87 Cloud native applications are horizontally scalable and operate within domain boundaries that divide them as 88 separate apps which communicate over the network via their APIs rather than as one monolithic entity. 89 We think cloud services require a fundamentally different approach to software creation and why Micro 3.0 90 was designed with this in mind. 91 92 ## Micro 3.0 aka M3O 93 94 Micro 3.0 (M3O) reimagines Micro as a platform for cloud native development. What does that mean? Well we think of 95 it as PaaS 3.0, a complete solution for source to running and beyond. Micro has moved from just being a Go 96 framework to incorporating a standalone server and hosted platform. Our hosted offering is called 97 [M3O](https://m3o.com), a hat tip to Micro 3.0 or M[icr]o, whichever way you want to see it. 98 99 Another way to think about it. What Git is to GitHub, Micro is to the M3O platform. Let's dig into it. 100 101 Micro 3.0 includes the following. 102 103 ### Server 104 105 The server is our abstraction for cloud infrastructure and underlying systems you might need for writing 106 distributed systems. The server encapsulates all of these concerns as gRPC services which you can 107 query via any language. The goal here is to say developers don't really need to be thinking about infrastructure 108 but what they do need is design patterns and primitives for building distributed systems. 109 110 <img src="/images/micro-3.0.png" /> 111 112 The server includes the following: 113 114 - **Authentication**: Auth whether its authentication or authorization is part of the system. Create JWT tokens, define access rules, use one system to govern everything in a simple and straight forward manner. Whether it’s for a user or a service. 115 116 - **Configuration**: Dynamic config management allows you to store relevant config that needs to be updated without having to restart services. Throw API keys and business logic related configuration into the secure config service and let your services pick up the changes. 117 118 - **Key-Value Storage**: We’re focused on best practices for microservices development which means keeping services mostly stateless. To do this we’re providing persistent storage on the platform. Key-Value allows you to rapidly write code and store data in the format you care about. 119 120 - **Event Streaming**: Distributed systems are fundamentally in need of an event driven architecture to breakdown the tight dependencies between them. Using event streaming and pubsub allows you to publish and subscribe to relevant events async. 121 122 - **Service Registry**: Micro and M3O bake in service discovery so you can browse a directory of services to explore your service APIs and enable you to query services by name. Micro is all about microservices and multi-service development. 123 124 - **Service Network**: Because you don't want to have to resolve those service names to addresses and deal with the load balancing aspect, the server bakes in a "service mesh" which will handle your inter-service requests (as gRPC) and route to the 125 appropriate instance. 126 127 - **Identity Proxy**: We include a separate identity proxy for external requests using gRPC via the CLI and other means. This enables you to query from your local machine or anywhere else using valid auth credentials and have it seamlessly work as if 128 you were in the platform itself. 129 130 - **API Gateway**: Finally there’s an API gateway that automatically exposes your services to the outside world over HTTP. Internally writing service to service using gRPC makes sense, but at the end of the day we want to build APIs consumed from clients via HTTP. 131 132 ### Clients 133 134 The server provides inter-service communication and two means of external communication with a HTTP API and gRPC proxy but that 135 experience is made much better when there's user experience on the client side that works. Right now we've got two ways of doing this. 136 137 - **Command Line**: The CLI provides a convenient and simple way to talk to the server via gRPC requests through the proxy. 138 The most convenient commands are builtin but every service you write also gets beautiful dynamic generated commands 139 for each endpoint. 140 141 - **gRPC SDKs**: Every service in the server is accessible via gRPC. We're code generating clients for the server itself 142 so you can access them from any language. What this enables is a wide array of experiences on the client side without 143 having to handcraft libraries for each language. 144 145 - **Web Interface**: Coming soon is a dynamically generated web interface that creates a simple query mechanism through a 146 browser for any of your services. We've got a http api, gRPC proxy and command line interface but feel like the browser 147 could use some love too. 148 149 ### Framework 150 151 One thing we really understood from our time working on go-micro was that the developer experience really matters. We 152 see Go as the dominant language for the cloud and believe most backend services in the cloud will be written in Go. For 153 that reason we continue to include a Service Framework which acts as a framework for building your services and accessing 154 the underlying systems of the server. 155 156 The Service Framework provides pre-initialised packages for all of the features of the server and creates a convenient 157 initialiser for defining your own services starting with `service.New`. A Service has a name, endpoints, contains 158 a server of its own and a client to query other services. The framework does enough for you but then attempts to 159 get out of your way so the rest is up to you. 160 161 A main package for a Micro service looks something like this 162 163 ```go 164 package main 165 166 import ( 167 "github.com/tickoalcantara12/micro/v3/service" 168 "github.com/tickoalcantara12/micro/v3/service/logger" 169 "github.com/micro/services/helloworld/handler" 170 ) 171 172 func main() { 173 // Create service 174 srv := service.New( 175 service.Name("helloworld"), 176 ) 177 178 // Register Handler 179 srv.Handle(new(handler.Helloworld)) 180 181 // Run the service 182 if err := srv.Run(); err != nil { 183 logger.Fatal(err) 184 } 185 } 186 ``` 187 188 When you want to make use of something like the Config service just import it like so. 189 190 ```go 191 import "github.com/tickoalcantara12/micro/v3/service/config" 192 193 val, err := config.Get("key") 194 ``` 195 196 You can find many more examples in [github.com/micro/services](https://github.com/micro/services). 197 198 ## Environments 199 200 From our experience writing software isn't constrained to a single environment. Most of the time we're doing 201 some form of local development followed by a push to staging and then production. We don't really see tools 202 capturing that workflow effectively. Thinking about how to do this now we've built in environments as 203 a first class system. 204 205 M3O offers 3 builtin environments; local, dev and platform. 206 207 - **Local** - is Micro running on your local machine 208 - **Dev** - is a free development environment in the cloud 209 - **Platform** - is a paid secure, scalable and supported production environment 210 211 Our goal here is to really direct the flow from local > dev > platform as the lifecycle for any backend service 212 development. Start by running the server locally, writing your code and getting it to work. Ship it to the 213 dev environment for further testing but also to collaborate with others and serve it publicly. Then if you're 214 interested in a scalable and supported production environment, pay for the platform environment. That's it. 215 216 Interact with the environments like so. 217 218 ```sh 219 # view the environments 220 micro env 221 222 # set the environment 223 micro env set dev 224 225 # add a new environment 226 micro env add foobar proxy.foo.com:443 227 ``` 228 229 Micro isn't constrained to our built in environments. You can add others as you wish. 230 231 232 ### Local Environment 233 234 The local environment is just that, your local laptop. Its where development starts and normally 235 this requires you to run all sorts of crazy infrastructure. Micro focuses on providing pluggable 236 abstractions as gRPC services so your service just talks gRPC directly to Micro and we hide the 237 details from you. Locally that means we're using best effort stuff like mdns, file storage, etc. 238 239 We've almost made it drop dead simple to start locally. You just run one command. 240 241 ```sh 242 micro server 243 ``` 244 245 This will boot all the services you need and let you build a service that will look identical 246 in any cloud environment running Micro as a Service. 247 248 Set your environment to the local server when using it. 249 250 ```sh 251 micro env set local 252 ``` 253 254 Curl `localhost:8080` with your namespace 255 256 ```sh 257 curl -H "Micro-Namespace: $NAMESPACE" "http://localhost:8080/helloworld?name=Alice" 258 ``` 259 260 Get your namespace like so 261 262 ```sh 263 micro user namespace 264 ``` 265 266 This might be blank locally but you'll get the idea for how namespace isolation works in a bit. 267 268 ### Dev Environment 269 270 The 'dev' environment is a free cloud hosted environment that provides Micro 3.0 as a Service. What we've 271 learned in the past few years is that open source is not enough. There's some great open source tools out there 272 but as soon as we get to deployment there's so many hurdles to overcome. The dev enviroment provides 273 everyone the ability to get up and running in minutes with the same tools you'd use for local development 274 in the cloud. 275 276 All you have to do is set the env to 'dev' and use it like local. 277 278 If you're using the dev environment URLs are `*.m3o.dev`. Find more details at [m3o.dev](https://m3o.dev) 279 280 ### Platform Environment 281 282 The 'platform' environment is a secure, scalable and supported production environment for where you'd likely 283 run customer facing services and products. This is a paid tier with 2x the resource limits of dev to start 284 including slack & email support along with SLAs. You can think of it as the equivalent of a production platform 285 you've come to know at any work place. 286 287 Our goal with Local, Dev and Platform is to invoke that workflow we've all come to know and expect as a real 288 product. These are totally separate environments and they're managed exactly as that with M3O as well. 289 290 ## Multi-Tenancy and Namespacing 291 292 With the advent of a system like kubernetes and a push towards the cloud we can see that there's really a need 293 to move towards shared resource usage. The cloud isn't cheap and we don't all need to be running separate 294 kubernetes clusters. In fact wouldn't it be great if we could share that? Well Micro is doing it. We build in 295 multi-tenancy using the same logic kubernetes does called Namespaces. 296 297 We've mapped this same experience locally so you get a rudimentary form of namespacing for local dev but 298 mostly we're making use of kubernetes namespaces in production along with a whole host of custom written 299 isolation mechanisms for authentication, storage, configuration, event streaming, etc so Micro 3.0 300 can be used to host more than one tenant. 301 302 Whether you decide to self host and share your cluster for dev, staging and production we felt like 303 multi-tenancy needs to become a defacto standard in 2020. How it works in practice. Each tenant 304 get's a namespace. That namespace has its own isolated set of users and resources in each subsystem. 305 When you make any request as a user or service, a JWT token is passed with that so the 306 underlying systems can route to the appropriate resources. 307 308 Once you've signed up to the dev environment your namespace will be set for you. You can get it using 309 the command 310 311 ```sh 312 micro user namespace 313 ``` 314 315 When you're using any sort of CLI commands, your namespace and auth token are automatically injected 316 into request including refreshing those tokens. The same happens for any of your services running 317 on Micro. If you want to use the http API or the public api url [api.m3o.dev] then go ahead 318 and grab your namespace and set the header as `Micro-Namespace`. 319 320 Additionally each namespace gets its own custom domain so the `foobar` namespace becomes `foobar.m3o.dev` 321 with say the helloworld service routing would be to `foobar.m3o.dev/helloworld`. 322 323 ## Source to Running 324 325 Micro was built out of a frustration with the existing tools out there. One of the things I've really 326 been saying for a long time is that I wanted "source to running" in just one command. With 327 Heroku we sort of got that but it really took too much away from us. Back in 2010 Heroku was focused 328 on monolithic Rails development. Since then I've really said Heroku took too much away and AWS gave 329 too much back. We needed something in between. 330 331 Micro can take your source code, from a local directory or a repo thats hosted on github, gitlab or bitbucket. 332 In one command it will upload or pull from the relevant place, package it as a container and 333 run it. That's it. Source to running in just one command. No more need to deal with the pipeline, 334 no more hacking away at containers and the container registries. Write some code and run it. 335 336 ## Development Model 337 338 Source to running is cool. It's what a PaaS is really for but one thing that's really been lacking even 339 with the new PaaS boom is a development model. As I eluded to, Heroku takes too much away and AWS 340 gives too much back. We're looking for a happy medium. One that doesn't require us to rely on VMs or 341 containers but on the other side doesn't limit us to monolithic development. 342 343 Micro has always focused on the practice of distributed systems development or microservices. The idea 344 of breaking down large monolithic apps into smaller separate services that do one thing well. To do 345 this we think you really have to bake the development model into the platform. 346 347 What we include is the concept of a Service which contains a Client and Server for both handling 348 requests and making queries to other services. We focus on standardisation around protobuf for API 349 definitions and using gRPC for the networking layering. 350 351 Not only that we're including pubsub for an event streaming architecture and other pieces like 352 nosql key-value storage and dynamic config management. We believe there are specific primitives 353 required to start building microservices and distributed systems and that's what Micro looks 354 to provide. 355 356 ## Multi Language Clients 357 358 One of the key learnings we had from the development of a Go framework called [go-micro](https://github.com/asim/go-micro) was 359 that we mostly use a single language for each platform we develop for such as web, mobile and so on. Cloud will be no different. 360 We support Go for the Cloud, but think there needs to be an ecosystem for consumption of Go services and potentially extending beyond 361 where there's no way around using python, java, ruby, rust or javascript. Because Micro's interface is gRPC we code generate gRPC 362 clients and allow any language to leverage the Micro server. 363 364 In the past multi-language clients have been pain stakingly hand crafted and one thing we learned from building a framework, 365 it's incredibly hard to replicate this across languages also. With gRPC we've really found a happy medium of saying, there's 366 a built in service framework you can use to write code really elegantly with Go but gRPC allows us to reduce the scope of the 367 surface area and provide strongly typed clients that can support a different model of development, one that might have 368 more scope for pushing microservices to wide scale adoption in a way that wasn't possible with frameworks. 369 370 We additionally include grpc-web generated clients which enable frontend to quickly and easily make use of typed javascript 371 clients to leverage the same development as the backend. We've seen grpc-web slowly gain adoption internally at various 372 companies and think this might extend to the public domain fairly rapidly as well. 373 374 See the [micro/client/sdk](https://github.com/tickoalcantara12/micro/tree/master/client/sdk) directory for the generated clients. These will be 375 pubished to their respective package managers in the near future. 376 377 ## Building API First Services 378 379 Micro was built to make microservices development much easier and to increase developer productivity on the backend, beyond 380 being able to consume those services using gRPC we think the world still really cares about HTTP/JSON based APIs and so 381 Micro include an API gateway which translates http/json to grpc requests automatically. This means everyone is building 382 API first services in the cloud without having to do anything. 383 384 Here's a quick example. 385 386 Say you write helloworld on the backend with the following proto 387 388 ```proto 389 syntax = "proto3"; 390 391 package helloworld; 392 393 service Helloworld { 394 rpc Message(Request) returns (Response) {} 395 } 396 397 message Request { 398 string name = 1; 399 } 400 401 message Response { 402 string msg = 1; 403 } 404 ``` 405 406 Then expose this as the "helloworld" service on the M3O platform. You'll instantly be able to access this as $namespace.m3o.dev/helloworld/message 407 408 We use path based resolution to map a http request to gRPC. So /[service]/[method] becomes [Service.Method]. If your microservice name doesn't match 409 the proto for whatever reason (you have multiple proto Services) then it works slightly differently e.g your service name is foobar then the endpoint 410 becomes `/foobar/helloworld/message`. 411 412 One neat hack we've picked up from web browser is auto detecting an endpoint so we can shorthand something to something like /helloworld. With the web 413 if an index.html page is found its served. In our case if we find the `Call` method in your proto we'll automatically use it so /helloworld/call just 414 shortens to /helloworld. 415 416 With Stripe, Twilio, Segment and others become huge API players, we think the world is going in that direction and you are probably building http apis 417 too. So Micro builds in this in as a first class primitive. In future we'll also look to include support for graphql. 418 419 ## Ten Commands 420 421 Alright so we talk a good game, but how easy is it? Well lets show you. 422 423 ```sh 424 # Install the micro binary 425 curl -fsSL https://install.m3o.com/micro | /bin/bash 426 427 # Set env to dev for the free environment in the cloud 428 micro env set dev 429 430 # Signup before getting started 431 micro signup 432 433 # Create a new service (follow the instructions and push to Github) 434 micro new helloworld 435 436 # Deploy the service from github 437 micro run github.com/micro/services/helloworld 438 439 # Check the service status 440 micro status 441 442 # Query the logs 443 micro logs helloworld 444 445 # Call the service 446 micro helloworld --name=Alice 447 448 # Get your namespace 449 NAMESPACE=$(micro user namespace) 450 451 # Call service via the public http API 452 curl "https://$NAMESPACE.m3o.dev/helloworld?name=Alice" 453 ``` 454 455 Easy right? We see this as the common flow for most service development. Its a fast iterative loop 456 from generating a new template to shipping it and querying to make sure it works. There's 457 additional stuff in the developer experience like actually writing the service but we think that's 458 a separate post. 459 460 ## Documentation 461 462 Another thing we really learned from the past is nothing like this works without great documentation 463 and tutorials. So we've written a whole suite of docs for Micro available at [micro.mu](https://micro.dev) 464 and provide help for using the M3O on [m3o.dev](https://m3o.dev/). 465 466 You can find other interesting resources at [Awesome Micro](https://github.com/micro/awesome-micro). 467 468 ## Licensing 469 470 Micro continues to remain open source but licensed using [Polyform Shield](https://polyformproject.org/licenses/shield/1.0.0/) 471 which prevents the software for being picked up and run as a service. This is to contend with AWS and others 472 running open source for profit without contributing back. It's a longer conversation for another day. 473 474 ## Motivations 475 476 We really believe that writing software for the cloud is too hard. That there's far too much choice and 477 time wasted focusing on how to piece everything together. There are tradeoffs to adopting a PaaS but 478 ultimately our focus is **developer productivity**. By choosing one tool and one way we stop thinking 479 about the how and just get down to what we're trying to build. 480 481 M3O and Micro 3.0 look at the state of distributed systems development in the cloud native era and 482 try to drastically simplify that experience with a platform that bakes in the development model 483 so you can just get back to writing code. 484 485 ## Deprecating Go Micro 486 487 We will now be ending support for [go-micro](https://github.com/micro/go-micro). Having personally 488 spent 6 years since inception on go-micro I feel as though its time to finally let it go. What 489 started as a tiny library to help write Kubernetes-as-a-Service back in 2014 turned into a widely 490 used open source framework for Go microservices development. Having now amassed more than 14k stars 491 you might wonder why we leave it behind. The truth is, while it solved a problem for many it never 492 became what it was intended for. 493 494 Go Micro was built on the premise that developers need a simpler way to build distributed systems. 495 With strongly defined abstractions and a pluggable architecture it did that well but that became 496 really unwieldy to manage. With an MxN matrix of complexity, Go Micro became the thing it was 497 trying to fight against. As we attempted to hone on this platform effort, it just became very 498 clear that to do that we'd need to start fresh. 499 500 Go Micro will live on as an independent library under my own personal account on GitHub but 501 it will no longer be supported as an official Micro project. Hopefully it finds second life in 502 some other ways but for now we say goodbye. 503 504 If you'd like to upgrade from Go Micro v2 to Micro v3 please see this [upgrade guide](/v2-to-v3-upgrade-guide). 505 506 ## Next Steps 507 508 You can use the Micro 3.O as a self-hosted open source solution locally, on a VPS or managed kubernetes, 509 whatever works for you. Our goal is to facilitate a vastly superior developer experience for building 510 services in the Cloud. Come join [Discord](https://discord.gg/hbmJEct) or [Slack](https://slack.m3o.com) 511 to chat more about it. And lastly head to to [m3o.com](https://m3o.com) if you're tired of the way you're 512 building software for today and want to learn of a better way that's going to make you 10x more productive. 513 514 So to revisit. To get started for free in the cloud based dev environment just run the following commands. 515 516 ```sh 517 # Install the micro binary 518 curl -fsSL https://install.m3o.com/micro | /bin/bash 519 520 # Set the env to the dev environment 521 micro env set dev 522 523 # Signup before getting started 524 micro signup 525 526 # Create a new service (follow the instructions and push to Github) 527 micro new helloworld 528 529 # Deploy the service from github 530 micro run github.com/micro/services/helloworld 531 532 # Check the service status 533 micro status 534 535 # Query the logs 536 micro logs helloworld 537 538 # Call the service 539 micro helloworld --name=Alice 540 541 # Get your namespace 542 NAMESPACE=$(micro user namespace) 543 544 # Curl it via the public http API 545 curl "https://$NAMESPACE.m3o.dev/helloworld?name=Alice" 546 ``` 547 548 If you want to test things out locally first 549 550 ```sh 551 # start the server locally 552 micro server 553 554 # set the environment to local 555 micro env set local 556 557 # login using user: admin pass: micro 558 micro login 559 ``` 560 561 And that's it! Please come chat with us in [Discord](https://discord.gg/hbmJEct) or [Slack](https://slack.m3o.com) and 562 [invite friends](https://m3o.dev/getting-started/invite-users) to test out the M3O platform. 563 564 To learn more about the M3O platform see the dev docs at [m3o.dev](https://m3o.dev). And for the open source docs 565 check out [micro.mu](https://micro.dev). 566 567 <br> 568 *Written by Asim Aslam* 569 <br> 570 Founder & CEO Micro