You have an awesome idea and you've built a cool application. Like any entrepreneur or developer, you really hope that your app will go viral and lots of users will want to use your app. Or maybe your enterprise has a business critical application that must be highly available and handle millions of transactions reliably. In the module Best Practices for Application Development, you'll learn design and development techniques to develop applications that are secure, scalable, resilient and highly available. Here are some key areas we'll discuss. Implement Microservices-based architectures with loosely coupled services that can be monitored and can fail gracefully on error. Consider issues such as compliance with local laws and user latency when deciding where to deploy your infrastructure. Be sure to implement build and release systems that enable continuous integration and delivery. While it's crucial that you have repeatable deployments, it's also important that you have the ability to roll back to a previous version of the app in a few minutes if you catch a bug in production. Finally, your journey to the Cloud is not an all-or-none scenario. Depending on your organization's maturity and comfort level with the Cloud, you can re-architect and migrate legacy applications in an incremental manner. In the module, we'll discuss all these areas and more. Applications that run in the Cloud must be built for global reach, scalability and high availability and security. Your application should be responsive and accessible to users across the world. Your application should be able to handle high traffic volumes reliably. The application architecture should leverage the capabilities of the underlying cloud platform to scale elastically in response to changes in load. Your application and the underlying infrastructure should implement security best practices. Depending on the use case, you might be required to isolate your user data in a specific region for security and compliance. In this presentation, you learn best practices related to Code and Environment Management, Design and Development, Scalability and Reliability, and Migration. Let's start with managing your application's code and environment. Store your application's code in a Code Repository, such as Git or Subversion. This will enable you to track changes to your source code and set up systems for continuous integration and delivery. Don't store external dependency such as jar files or external packages in your code repository. Instead, depending on your application platform, explicitly declare your dependencies with their versions, and install them using a dependency manager. For example, for a Node.js application, you can declare your application dependencies in a package.json file, and later install them using the NPM install command. Separate your application's configuration settings from your code. Don't store configuration settings as constants in your source code. Instead, specify configuration settings as environment variables. This enables you to easily modify settings between development test and production environments. Instead of implementing a monolithic application, consider implementing or refactoring your application as a set of microservices. In a monolithic application, the code base becomes bloated over time. It can be difficult to determine where code needs to be changed. Packages or components of the application can have tangled dependencies. For example, in this monolithic application, the UI, order, payment, shipping, and other components are all part of a single large code base. The entire application needs to be deployed and tested even if a change is made to a small part of the code base. This increases the effort and risk when making future changes and bug fixes. Microservices enable you to structure your application components in relation to your business boundaries. In this example, the UI, payment, shipping, and other services are all broken up into individual microservices. The code base for each service is modular. It's easy to determine where code needs to be changed. Each service can be updated and deployed independently without requiring the consumers to change simultaneously. Each service can be scaled independently depending on load. Make sure to evaluate the costs and benefits of optimizing and converting a monolithic application into one that uses a microservices architecture. Remote operations can have unpredictable response times and can make your application seem slower. Keep the operations and the user thread at minimum. Perform back-end operations asynchronously. Use event driven processing where possible. For example, if your application processes images that are uploaded by a user, you can use a Google Cloud Storage bucket to store the uploaded images. You can then implement Google Cloud Functions that are triggered whenever a new image is uploaded. Cloud Functions can process the image and upload the results to a different Cloud Storage location. Design application components so that they are loosely coupled at one time. Tightly coupled components can make an application less resilient to failures, spikes in traffic, and changes to services. An intermediate component such as a message queue can be used to implement loose coupling, perform asynchronous processing, and buffer requests in case of spikes in traffic. You can use a cloud pop subtopic as a message queue. Publishers can publish messages to the topic, and subscribers can subscribe to messages from this topic. In the context of HTTP API payloads, consumers of HTTP APIs should bind loosely with the publishers of the API. In the example, the email servers retrieves information about each customer from the customer service. The customer service returns the customer's name, age, and email address and its payload. To send an email, the email service should only reference the name and email fields of the payload. It should not attempt to bind with all the fields in the payload. This method of loosely binding fields will enable the publisher to evolve the API and add fields to the payload in a backwards compatible manner. Implement application component so that they don't store state internally or access a shared state. Accessing a shared state is a common bottleneck for scalability. Design each application so that it focuses on compute tasks only. This approach enables you to use a worker pattern, to add or remove additional instances of the component for scalability. Application components should start up quickly to enable efficient scaling, and shut down gracefully when they receive a termination signal. For example, if your application needs to process streaming data from IoT devices, you can use a Google Cloud pop subtopic to receive the data. You can then implement Google Cloud functions that are triggered whenever a new piece of data comes in. The Google Cloud Function can process, transform, and store the data. Alternatively, your application can subscribe to the pop subtopic that receives the streaming data. Multiple instances of your application can spin up and process the messages in the topic, and split the workload. These instances can automatically be shut down when there are very few messages to process. To enable elastic scaling, you can use any compute environments such as Google Compute Engine with Google Cloud Load Balancing, Google Container Engine, or Google App Engine. With either approach, you don't have to develop code to manage concurrency or scaling. Your application scales automatically depending on the workload. So you're performing asynchronous operations and your database queries are doing well. But your application still seems a bit slow. What can you do? Cache-ing content can improve application performance and lower network latency. Cache application data that is frequently accessed or that is computationally intensive to calculate each time. When a user requests data, the application component should check the cache first. If data exists in the cache, meaning the TTL has not expired. The application should return the previously cached data. If the data does not exist in the cache or has expired, the application should retrieve the data from back-end data sources, and re-compute results as needed. The application should also update the cache with the new value. In addition to cache-ing application data in a cache such as Memcached or Redis, you can also use a content delivery network to cache webpages. Cloud Content Delivery network can cache load balanced front-end content that comes from compute engine VM instance groups, or static content that is served from Cloud Storage. For more information about using cloud CDN, see the downloads and resources page. Implement API gateways to make back-end functionality available to consumer applications. Here's an example of an ordinary API deployed on Cloud endpoints. You can use Google Cloud endpoints to develop, deploy, protect and monitor APIs based on the open APIs specification or GRPC. Further, the API for your application can run on back-end such as Google App engine, Google Container Engine, or Google Compute Engine. If you have legacy applications that cannot be re-factored and move to the Cloud, consider implementing APIs as a facade or adapter link. Each consumer can then invoke these modern APIs to retrieve information from the back-end, instead of implementing functionality to communicate using outdated protocols and desperate interfaces. Here's an example of a payment API deployed on RPG. Using the RPG API platform, you can design, secure, analyze, and scale your APIs for legacy back-ends. For more information about the RPG API platform, see the downloads and resources page.