DEV Community

Cover image for Build A Todo API With .NET And Appwrite
Aditya Oberai for Appwrite

Posted on • Updated on

Build A Todo API With .NET And Appwrite

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.

Steve Harvey excited

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).

Sign Up For Appwrite Cloud

After that, you can go ahead and create your first project by clicking on the Create Project button.

Create a new Appwrite project

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.

Create an API Key

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

Database Attributes

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.

Please make sure to install the .NET 7 SDK on your system, if you haven't already.

Step 1: Create a Minimal API project

In order to create a .NET minimal API project, you must open your terminal and run the following command:

dotnet new web -o TodoApi
Enter fullscreen mode Exit fullscreen mode

This will generate a minimal API project in the ./TodoApi directory using the scaffolding offered along with the .NET CLI.

You can go ahead and enter the directory and open it in your preferred code editor.

Step 2: Install Appwrite SDK and Setup the Project Configuration

Now that a project has been created, let's install the Appwrite SDK:

dotnet add package Appwrite
Enter fullscreen mode Exit fullscreen mode

This will install the Appwrite 0.4.2 NuGet package, which includes the current latest version of the SDK.

After that, you can open the appsettings.json file and add the following (after the Logging and AllowedHosts fields):

  "Appwrite": {
    "Project_Id": "[PROJECT_ID]",
    "Database_Id": "[DATABASE_ID]",
    "Collection_Id": "[COLLECTION_ID]",
    "Api_Key": "[API_KEY]"
  }
Enter fullscreen mode Exit fullscreen mode

This is where we will need the Project Id, Database Id, Collection Id, and API key you grabbed from your Appwrite project earlier.

Step 3: Create the Todo Model

Once the project is setup and configured, first let's create a model for the Todos themselves. Create a new class Todo within the project as follows:

public class Todo
{
    public string Description { get; set; }
    public bool IsCompleted { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

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 directives

using Appwrite;
using Appwrite.Services;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Get necessary Appwrite configuration from appsettings.json

var projectId = builder.Configuration["Appwrite:Project_Id"];
var apiKey = builder.Configuration["Appwrite:Api_Key"];
var databaseId = builder.Configuration["Appwrite:Database_Id"];
var collectionId = builder.Configuration["Appwrite:Collection_Id"];

// Initialize object for Appwrite Client

var client = new Client()
    .SetEndpoint("https://cloud.appwrite.io/v1")
    .SetProject(projectId)
    .SetKey(apiKey);

// Initialize object for Databases service APIs

var databases = new Databases(client);

// Create CRUD API endpoints

app.MapGet("/todos", async () =>
{
    try
    {
        var todos = await databases.ListDocuments(
            databaseId: databaseId,
            collectionId: collectionId);

        return Results.Ok(todos);
    }
    catch (AppwriteException e)
    {
        return Results.NotFound(new Dictionary<string, string> { { "message", e.Message } });
    }
})
.WithName("GetAllTodos");

app.MapGet("/todos/{id}", async (string id) =>
{
    try
    {
        var todo = await databases.GetDocument(
            databaseId: databaseId,
            collectionId: collectionId,
            documentId: id);

        return Results.Ok(todo);
    }
    catch(AppwriteException e)
    {
        return Results.NotFound(new Dictionary<string,string> { { "message", e.Message } });
    }
})
.WithName("GetTodo");

app.MapPost("/todos", async (Todo todo) =>
{
    try
    {
        var document = await databases.CreateDocument(
            databaseId: databaseId,
            collectionId: collectionId,
            documentId: ID.Unique(),
            data: todo);

        return Results.Created($"/todos/{document.Id}", document);
    }
    catch (AppwriteException e)
    {
        return Results.BadRequest(new Dictionary<string, string> { { "message", e.Message } });
    }
})
.WithName("CreateTodo");

app.MapPut("/todos/{id}", async (string id, Todo todo) =>
{
    try
    {
        var document = await databases.UpdateDocument(
            databaseId: databaseId,
            collectionId: collectionId,
            documentId: id,
            data: todo);

        return Results.NoContent();
    }
    catch (AppwriteException e)
    {
        return Results.BadRequest(new Dictionary<string, string> { { "message", e.Message } });
    }
})
.WithName("UpdateTodo");

app.MapDelete("/todos/{id}", async (string id) =>
{
    try
    {
        var document = await databases.DeleteDocument(
            databaseId: databaseId,
            collectionId: collectionId,
            documentId: id);

        return Results.Ok(document);
    }
    catch (AppwriteException e)
    {
        return Results.NotFound(new Dictionary<string, string> { { "message", e.Message } });
    }
})
.WithName("DeleteTodo");

app.Run();
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

GitHub logo adityaoberai / .NET-Appwrite-Todo-API

Todo CRUD API built with Appwrite + .NET

.NET + Appwrite Todo API

Description

Todo CRUD API built with Appwrite Cloud and .NET 7

Installation

Appwrite Setup

  • Sign up for Appwrite Cloud

    Register for Appwrite Cloud

  • Create your first project

    Create a project

  • Create an API Key with the scopes documents.read and documents.write

    API Key scopes

  • Create a database, followed by a collection, and create the following attributes

    Attribute ID Type Size Default Value Required Array
    description string 255 Yes No
    isCompleted boolean Yes No

    Collection attributes

  • Keep your Project Id, Database Id, Collection Id, and API Key saved for the project setup

Project Setup

  • Install the .NET 7 SDK if you haven't already

  • Clone the repository

    https://github.com/adityaoberai/.NET-Appwrite-Todo-API.git
    Enter fullscreen mode Exit fullscreen mode
  • Restore all NuGet packages

    dotnet restore
    Enter fullscreen mode Exit fullscreen mode
  • Enter the project directory

    cd AppwriteCrudApi/
    Enter fullscreen mode Exit fullscreen mode
  • Add the Project Id, Database Id, Collection Id, and API Key you saved from your Appwrite project in the appsettings.json file

  • Run the project

    dotnet run
    Enter fullscreen mode Exit fullscreen mode
  • Open the following URL in your browser

    https://localhost:7248/swagger
    

    OR

    http://localhost:5023/swagger
    





Moving Forward 🛣️

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.

If you'd like to learn more about Appwrite, check out the official documentation and join our Discord server.

Stay safe, and happy building :)

Top comments (2)

Collapse
 
marcinjakubowski profile image
Marcin Jakubowski

Is there a more comprehensive example out there? Like a todo app that lets you log in using different auth providers, that saves todos per user, lets you add an image to the todo for example (to showcase storage API), etc., with a frontend and a backend - if one is necessary, I'm not quite sure if it can be done frontend only, and how, that's why it'd be great to have a full, comprehensive example you could follow from A to Z.

Collapse
 
adityaoberai profile image
Aditya Oberai

We do have some such examples that directly use Appwrite in the front-end for our Web SDK.

You can check them out here: appwrite.io/docs/getting-started-f...

As for .NET, I'll be working on more such apps soon. We do have the Appwrite .NET Playground though: github.com/appwrite/playground-for...