Last week, Appwrite launched its .NET SDK in Beta to support C# and .NET in building server-side apps more efficiently and productively. The announcement had me very excited because .NET and C# are among my absolute favourite technologies!
To help showcase how Appwrite can be used be used with .NET, I built a basic Todo API project with all fundamental CRUD functionalities. Let's learn how you can build such a project and leverage .NET 7 and Appwrite to build powerful server-side applications.
Setup Your Appwrite Instance ☁️
First things first, we need to setup an Appwrite instance to build this project.
If you're trying Appwrite for the first time, Appwrite is an open-source Backend-as-a-Service platform that provides you with pre-built APIs for fundamental services such as databases, storage, authentication, cloud functions, etc., that you need to build any application you'd like. You can either self-host Appwrite using Docker, or sign up for our managed service, Appwrite Cloud.
Step 1: Create an Appwrite Project
The simplest and quickest way to get your Appwrite project up and running is to sign up for Appwrite Cloud (you can login if you already have an account).
After that, you can go ahead and create your first project by clicking on the Create Project button.
Step 2: Create an API Key
Once you have created your Appwrite project, you must go ahead and create an API Key. You can do so by clicking on the API Key button visible in the Integrate With Your Server section.
While creating your API Key, make sure to select the documents.read and documents.write scopes.
Step 3: Create a Database
Once your API key is created, you need to setup a database for the API to communicate with. Go to the Databases tab on the left, and create a database, followed by a collection. Within this collection, we need to create the following attributes:
Attribute ID
Type
Size
Default Value
Required
Array
description
string
255
Yes
No
isCompleted
boolean
Yes
No
These attributes, description and isCompleted will contain the details of the todos that we create and consume for ourselves.
Once all these steps are complete, grab your Project Id, Database Id, Collection Id, and API Key, as we will need these when we create the .NET API.
Create A .NET 7 Minimal API 🧑💻
Now that our Appwrite project is configured properly, we are ready to build the .NET Web API.
This model corresponds with the attributes we created in the collection in our Appwrite database, and will be especially important when we add or update any todos in the database.
Step 4: Write the Appwrite CRUD functions
Now that we're all set, let's create the API endpoints and CRUD functions themselves. Head over to the Program.cs file and replace it with the following code:
// Relevant using directivesusingAppwrite;usingAppwrite.Services;varbuilder=WebApplication.CreateBuilder(args);varapp=builder.Build();// Get necessary Appwrite configuration from appsettings.jsonvarprojectId=builder.Configuration["Appwrite:Project_Id"];varapiKey=builder.Configuration["Appwrite:Api_Key"];vardatabaseId=builder.Configuration["Appwrite:Database_Id"];varcollectionId=builder.Configuration["Appwrite:Collection_Id"];// Initialize object for Appwrite Clientvarclient=newClient().SetEndpoint("https://cloud.appwrite.io/v1").SetProject(projectId).SetKey(apiKey);// Initialize object for Databases service APIsvardatabases=newDatabases(client);// Create CRUD API endpointsapp.MapGet("/todos",async()=>{try{vartodos=awaitdatabases.ListDocuments(databaseId:databaseId,collectionId:collectionId);returnResults.Ok(todos);}catch(AppwriteExceptione){returnResults.NotFound(newDictionary<string,string>{{"message",e.Message}});}}).WithName("GetAllTodos");app.MapGet("/todos/{id}",async(stringid)=>{try{vartodo=awaitdatabases.GetDocument(databaseId:databaseId,collectionId:collectionId,documentId:id);returnResults.Ok(todo);}catch(AppwriteExceptione){returnResults.NotFound(newDictionary<string,string>{{"message",e.Message}});}}).WithName("GetTodo");app.MapPost("/todos",async(Todotodo)=>{try{vardocument=awaitdatabases.CreateDocument(databaseId:databaseId,collectionId:collectionId,documentId:ID.Unique(),data:todo);returnResults.Created($"/todos/{document.Id}",document);}catch(AppwriteExceptione){returnResults.BadRequest(newDictionary<string,string>{{"message",e.Message}});}}).WithName("CreateTodo");app.MapPut("/todos/{id}",async(stringid,Todotodo)=>{try{vardocument=awaitdatabases.UpdateDocument(databaseId:databaseId,collectionId:collectionId,documentId:id,data:todo);returnResults.NoContent();}catch(AppwriteExceptione){returnResults.BadRequest(newDictionary<string,string>{{"message",e.Message}});}}).WithName("UpdateTodo");app.MapDelete("/todos/{id}",async(stringid)=>{try{vardocument=awaitdatabases.DeleteDocument(databaseId:databaseId,collectionId:collectionId,documentId:id);returnResults.Ok(document);}catch(AppwriteExceptione){returnResults.NotFound(newDictionary<string,string>{{"message",e.Message}});}}).WithName("DeleteTodo");app.Run();
Test The Application 🌐
Now that the API is ready, we can go ahead and test it! Go ahead and run the following command:
dotnet watch
You can now test out all the endpoints locally using cURL, Postman, or any other API testing tool that can send HTTP Requests.
API Endpoint
Description
Request Body
GET /todos
Gets all todos
GET /todos/{id}
Gets a todo by Id
POST /todos
Add a todo
Todo item: { "description": "<Enter todo description>", "isCompleted": false }
PUT /todos/{id}
Updates a todo
Todo item: { "description": "<Enter todo description>", "isCompleted": false }
DELETE /todos/{id}
Deletes a todo
You can also check out the following repository, where the minimal API comes with a Swagger UI to make API testing even simpler.
Thank you so much for reading and trying out this tutorial, folks! If you liked it, please consider sharing this blog with your peers and social media.