Announcing Appwrite 0.14 with 11 Cloud Function Runtimes! 🥳
Tags: news, opensource, cloud, webdev
Published: 2022-05-17 15:04:13

We're back with yet another Appwrite release! Appwrite 0.14 is now LIVE with a lot more improvements! With the new release we focused heavily on features that the Appwrite community requested the most. With many exciting features and important bug fixes, Appwrite 0.14 now enables even more flexibility, performance, and integrations to build your amazing next project! Let’s deep dive and learn what this release has to offer. 🏊‍♀️

## ⏰ TL;DR

Two areas that received the most attention are **Events** and **Certificates**. With the new event model, you can now trigger actions with a lot more precision. The improvements around certificates makes it more easy, scalable, and reliable to generate and manage Let's Encrypt generated certificates. You can now lean back on your chair and enjoy the trusty 🔐 green lock in front of your domain 🍹

Alongside these features, we introduced new **OAuth providers**, **Storage Adapters**, and **Function Runtimes** to support an even wider range of amazing applications on more platforms. Some small features you can get excited about are **Wildcard Hostnames**, **Async/Await support in Swift**, and the ability to ignore files using the **Appwrite CLI**. We closed off the release with bug fixes and quality of life improvements around the **Appwrite Console UI** and **API signatures**.

> ### New to Appwrite?
[Appwrite](http://appwrite.io/) is an open-source back-end-as-a-service that abstracts all the complexity of building a modern application by providing you with a set of REST and Realtime APIs for your core back-end needs. Appwrite takes the heavy lifting for developers and handles user authentication and authorization, databases, file storage, cloud functions, webhooks, and much more!

---

## 🧠 Event Model, the Smart Way

![Event Model](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tygmqeb5af7ovigb59g0.png)
 
We're thrilled to introduce support for a lot more events, allowing your configuration to be as specific or as generic as you require. Previously, the following event would be triggered, for instance, when a new database document was created:

```
database.collections.create
```

This is great, but what if you have dozens of collections? You would end up with many events triggered for each collection. What if you're only interested in events from one of these collections? 

With the new event model, we can specify specific resources we are interested in. The same example above could be written as follows if we were only interested in documents from the `[MY_COLLECTION]` collection:

```
collections.[MY_COLLECTION].documents.*.create
```

As you can see, we specified, we are only interested in events from the `[MY_COLLECTION]` collection in the new syntax. You can also notice the `*` symbol indicating we are interested in all documents inside a collection. This new syntax will allow developers to get exceptionally specific with their events and reduce the number of unwanted webhooks and function executions to **zero**.

---

## 🔐 Certificates You Can Trust

Certificate generation was fully refactored with a focus on simplicity and reliability. We introduced the concept of a main domain to ensure we don't generate certificates for domains you don't own. 

Next, we updated the way we delete domains and certificates to ensure we only have one certificate per domain, and we delete it only once no domain needs it. This allows proper usage of the same domain under multiple Appwrite projects.

We then introduced a mechanism to automatically retry certificate generations. A certificate generation can fail for a lot of reasons like a 5XX error, NS downtime, DNS miss-configuration, cache etc. Some of them are recoverable while some others are not. The `maintenance` and `certificates` workers will now retry the certificate renewals and generations for up to 5 attempts to try and overcome the recoverable errors.

No need to worry about failed requests, since you will now receive **an email notification** every time a certificate generation fails, so you can investigate it 👀 Just ensure your email is set in the `.env` file.

Lastly, we introduced a new CLI command which comes in handy if you want to force the generation of a certificate for a specific domain:

```bash
docker-compose exec appwrite ssl domain="api.myapp.com"
```	

---

## 👪 C++, .NET, Java & Kotlin join the party!

![New Runtimes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n6u01r402pr8mb3ykx5y.png)
  
Let's welcome on board four new runtimes 🎉 A well-established **Java** and its friend **Kotlin** have joined the Appwrite Runtime family. They've also invited **C++** and **.NET** to ensure Appwrite developers can have the best possible experience writing code in a language they love the most. All these runtimes are now available when creating a new Appwrite Function, and provide the same breathtaking performance we shared with you in the previous Appwrite release. 

We didn't stop there! After a lot of feedback, we implemented **Function Ignores** to allow developers using [Appwrite CLI](https://appwrite.io/docs/command-line) to specify the files that will be part of a deployment. This comes in handy when you don't want to deploy files like your `.env` along with your functions. Another great use-case would be ignoring local dependencies that are not necessary for deployment but are required by your IDE to get proper typing support. With smarter ignores in your Appwrite Function, deployment can be safe and rapidly faster. All of this can be done either by having a `.gitignore` file in your function directory or by a manual configuration in your `appwrite.json` file.

---

## 💪 Flexible Wildcard Hostnames

If you've built a website before, or interacted with the Appwrite API, chances are, you've come across CORS issues. It all comes down to Appwrite protecting your backend from untrusted sources. Thankfully, in Appwrite 0.14 you can now use the wildcard symbol `*` to support all subdomains of a trusted domain. For instance, you could allow `*.mydomain.com` to trust all your subdomains. If you feel adventurous, you could even do `myapp.*` or simply `*`. Be aware, that the more you allow, the less control you have over who can use your backend!

---

## ⛔️ Say No to Callback Hells

With Appwrite 0.14 we have rewritten our Swift SDK to allow better code readability thanks to **async/await** support introduced in Swift 5.5. Awaiting asynchronous code not only allows you to write code in a simple top-to-bottom code block but also prevents callback hell and re-throwing errors.

Let’s start by looking at how a piece of code could look like without async/await support:

```swift
func prepareConnection() {
    getJWT() { jwt in
        print(jwt) // Do stuff with JWT
    }
}

func getJWT(completion: @escaping ((String) -> Void)) {
    account.createJWT() { result in
        switch result {
            case .failure(let error):
                fatalError(error.message)
            case .success(let response):
                completion(response.jwt)
        }
    }
}
```

As you can see, we had to use a `completion` callback and the code looks overall really complex. Let’s enhance the same code with async/await support:

```swift
func prepareConnection() async throws {
    let jwt = try await getJWT()
    print(jwt) // Do stuff with JWT
}

func getJWT() async throws -> String {
    let response = try await account.createJWT()
    return response.jwt
}
```

Wow, what a change! By marking methods as `async` and using `await` to get data from Appwrite, we can achieve exact same logic as previously while keeping the code simple and succinct.

---

## 🛰️ New Providers Everywhere - OAuth + Storage! 

![Storage Adapters](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/27hm1ktxzveupscticmt.png)
 
 
We introduced 3 new OAuth providers **Zoom, Okta, Auth0**, and 3 new storage adapters **Linode, Backblaze, Wasabi**. Appwrite was and always will play well with other technologies so the decision regarding the technology stack is in your hands, not ours.

---

## 🤩 And Much More!
 
Alongside all the amazing stuff, we also decided to clear some confusion around user deletion. We renamed our Client SDK method from `account.delete()` to `account.updateStatus()`. The new naming convention aims to indicate that the account is not deleted; instead the status is updated. To completely delete an account, you can use the Appwrite Dashboard or the `users.delete()` method in the Server SDK. Keep in mind we no longer reserve a user ID after deletion, so make sure to also delete all user-generated content and invalidate permissions before deleting the user to prevent any data leaks.

![Teams](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mh0ijxmjcx8qncqyv6ws.png)

Appwrite Console (Dashboard) received a lot of attention in this update! A shiny new component for the new event model was added, a verification toggle on the user has been implemented, and an activity tab was added to the teams page. We also introduced better logs for function deployments, fixed missing attribute icons in the Database screens and project logos, and updated the enum attribute dropdown to show correct values.

## 📚 Learn More

This was only a tip of the iceberg of what Appwrite 0.14 has to offer! Check out the [official release notes](https://github.com/appwrite/appwrite/blob/master/CHANGES.md) and stay tuned for more blog posts! In upcoming weeks we will describe all features in their own separate blogposts to give them well-deserved spotlights. We can't wait to see what you build with [Appwrite](https://appwrite.io/)! 😎