This project demonstrates how to create and deploy a RESTful API using TypeSpec and .NET, with Azure Cosmos DB for persistence and Azure Container Apps for hosting.
TypeSpec is a language for describing cloud service APIs and generating other API description languages, client and service code, documentation, and other assets. TypeSpec provides highly extensible core language primitives that can describe API shapes common among REST, GraphQL, gRPC, and other protocols.
You must have an Azure Subscription. If you don't have one, create one here for free.
Open in Codespaces or Visual Studio Developer Container. This has all prereqs installed for you.
Sign into Azure Developer CLI.
azd auth login
Deploy to Aazure
azd up
Use this readme to learn the process of how this repo was built.
- Node.js (v16 or later)
- .NET SDK (v9.0 or later)
- Azure CLI
- Azure Developer CLI
First, make sure you have Node.js and .NET installed. Then, install the TypeSpec compiler globally:
npm install -g @typespec/compiler
Install TypeSpec extension for VS Code for a better development experience:
code --install-extension ms-typespec.typespec-vscode
Verify TypeSpec is installed correctly:
tsp --version
- Create a new directory for your project:
mkdir typespec-api
cd typespec-api
- Initialize a new TypeSpec project:
npm init -y
npm install --save-dev @typespec/compiler @typespec/http @typespec/rest @typespec/openapi @typespec/openapi3 @typespec/http-server-csharp
- Create a main.tsp file with your API specification:
import "@typespec/http";
using Http;
@service(#{ title: "Widget Service" })
namespace DemoService;
model Widget {
id: string;
weight: int32;
color: "red" | "blue";
}
model WidgetList {
items: Widget[];
}
@error
model Error {
code: int32;
message: string;
}
@route("/widgets")
@tag("Widgets")
interface Widgets {
/** List widgets */
@get list(): WidgetList | Error;
/** Read widgets */
@get read(@path id: string): Widget | Error;
/** Create a widget */
@post create(@body body: Widget): Widget | Error;
/** Update a widget */
@ update(@path id: string, @body body: MergeUpdate<Widget>): Widget | Error;
/** Delete a widget */
@delete delete(@path id: string): void | Error;
}
Create a tspconfig.yaml
file to configure the TypeSpec emitters:
emit:
- "@typespec/openapi3"
- "@typespec/http-server-csharp"
options:
"@typespec/openapi3":
emitter-output-dir: "{output-dir}/server/wwwroot"
openapi-versions:
- 3.1.0
"@typespec/http-server-csharp":
emitter-output-dir: "{output-dir}/server/"
Generate the server code using TypeSpec:
tsp compile .
This will create a new server directory with a fully functional .NET API server, including controllers, models, and an OpenAPI specification available from a Swagger UI.
- Add the necessary NuGet packages to your server project:
cd server
dotnet add package Microsoft.Azure.Cosmos
dotnet add package Azure.Identity
Create Azure directory and CosmosDbRegistration.cs file in your server project to handle Cosmos DB integration.
Implement the WidgetsCosmos class to handle CRUD operations with Cosmos DB.
Update Program.cs to use Cosmos DB instead of mock data.
- Create an
azure.yaml
file in the project root:
name: azure-typespec-scaffold-dotnet
metadata:
template: [email protected]
services:
api:
project: ./server
host: containerapp
language: dotnet
pipeline:
provider:
This uses the latest Azure Developer CLI (AZD) and .NET abilities to deploy a .NET app to Azure Container apps without a container defintion.
- Create Bicep templates in an
infra
directory to define the Azure resources with Azure Verified Modules:
The main.bicep file defines:
- Azure Cosmos DB with serverless configuration
- Azure Container Registry
- Azure Container Apps Environment
- Azure Container App to host the API
- Log Analytics Workspace
- Managed Identities for secure connections
- Deploy to Azure using Azure Developer CLI:
azd auth login
azd up
This command:
- Provisions all required Azure resources using the Bicep templates
- Builds the .NET application
- Packages it into a container image
- Deploys the container to Azure Container Apps
Once deployed, you can access your API using Swagger UI:
- Get the URL for your deployed Container App:
azd env get-values
Open the URL in your browser to access the Swagger UI interface.
Use the Swagger UI to test your API endpoints:
- GET /widgets - List all widgets
- GET /widgets/{id} - Get a specific widget
- POST /widgets - Create a new widget
- /widgets/{id} - Update a widget
- DELETE /widgets/{id} - Delete a widget
- main.tsp: TypeSpec API definition
- tspconfig.yaml: TypeSpec compiler configuration
- server/: Generated .NET API server
- azure/: Custom implementations for Azure services
- generated/: Auto-generated TypeSpec code
- Program.cs: Application entry point
- infra/: Azure infrastructure as code (Bicep)
- azure.yaml: Azure Developer CLI configuration
- Add authentication and authorization
- Implement monitoring and logging
- Add Actions for CI/CD
- Explore more TypeSpec features for complex APIs