# Build a web API

> Create an ASP.NET Core host in Alice, map endpoints, and run the checked example.

Canonical: https://alice-lang.org/documentation/guides/web/

[Documentation index](https://alice-lang.org/documentation/llms.txt) · [Complete book](https://alice-lang.org/llms-full.txt)

## Use ASP.NET Core directly

An Alice API can call ASP.NET Core's builder, routing, and response APIs. Run this kind of application locally: the browser playground is not a listening web server.

Create a package:

```sh
alice new hello-api
cd hello-api
```

## Check web prerequisites

The host needs .NET 10's ASP.NET Core targeting pack for compilation and `Microsoft.AspNetCore.App` for execution. Run `dotnet --list-runtimes` and check that the ASP.NET Core runtime is present. Some Linux package distributions split these components into separate packages; use the [platform installation guide](https://learn.microsoft.com/en-us/dotnet/core/install/linux) if a framework pack or runtime is missing. A base .NET runtime alone cannot host this application.

## Add the shared framework

Create `Directory.Build.props` in the package directory:

```xml
<Project>
  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
</Project>
```

MSBuild discovers these settings through the generated project. The manifest remains the source of truth for package metadata and dependencies.

## Define a route

Replace `src/main.al` with:

```alice
using Microsoft.AspNetCore.Builder
using Microsoft.AspNetCore.Http

record Health(status : String)
module Routes
  def self.health : IResult
    Results.Ok(Health.new("ok"))
  end
end

builder = WebApplication.CreateBuilder(ARGV)
app = builder.Build()
app.MapGet("/health", -> { Routes.health })
app.Run()
```

The record supplies the JSON shape. `Routes.health` returns an `IResult`, giving routing a clear response type. A typed or otherwise unambiguous lambda binds the handler to the appropriate .NET overload.

## Run and request

```sh
alice run -- --urls http://127.0.0.1:5080
```

In a second terminal:

```sh
curl http://127.0.0.1:5080/health
# {"status":"ok"}
```

`ARGV` passes the host options through to ASP.NET Core. Stop the server with `Ctrl C`.

## Validate input before calculation

The repository's quote API demonstrates query parsing, integer-cent amounts, quantity bounds, a pricing library, and HTTP 400 responses for invalid data. It avoids converting malformed strings directly into prices.

From the compiler checkout:

```sh
alice build examples/web/aspnet
alice run examples/web/aspnet/api -- --urls http://127.0.0.1:5080
```

```sh
curl 'http://127.0.0.1:5080/quote?unitPriceCents=1250&quantity=10'
# {"subtotalCents":12500,"discountCents":1250,"totalCents":11250}
```

See the [complete source and setup](https://github.com/alicelanguage/alice/tree/main/examples/web/aspnet). Its pricing library has Alice tests, and the example verifier exercises real HTTP responses. When extracting repository examples, preserve their framework references and SDK settings.

## Keep domain rules testable

Put pricing, validation, and other deterministic decisions in methods or a library package. Keep route handlers responsible for parsing, calling those rules, and choosing an HTTP result. Test the rules with `alice test`, then check the listening routes separately. A passing compilation alone does not prove the HTTP behavior.

## Continue reading

- Previous: [Use .NET and NuGet](https://alice-lang.org/documentation/guides/dotnet.md)
- Next: [Build games and desktop programs](https://alice-lang.org/documentation/guides/games.md)
