Skip to main content

REST Minimal API Sample

The ECGrid-REST-dotnet10-MinimalAPI project shows how to expose a lightweight ASP.NET Core Minimal API that proxies key ECGrid REST endpoints. This pattern is useful when you need to add authentication, logging, or transformation between your own clients and the ECGrid API.

Project Location

samples/rest/ECGrid-REST-dotnet10-MinimalAPI/

What It Demonstrates

  • ASP.NET Core Minimal API with WebApplication.CreateBuilder
  • MapGet / MapPost endpoint registration with inline handlers
  • IHttpClientFactory injected directly into endpoint handlers
  • ECGrid API key applied at the client level — not re-exposed to callers
  • Exposed proxy endpoints: GET /inbox, POST /upload, GET /parcel/{id}

Key Files

FilePurpose
Program.csAll endpoint registration and handler logic
appsettings.jsonBase configuration
Models/Shared response model classes

Configuration

{
"ECGrid": {
"BaseUrl": "https://rest.ecgrid.io",
"ApiKey": "",
"MailboxId": 0
}
}

Set the API key locally with user-secrets:

cd samples/rest/ECGrid-REST-dotnet10-MinimalAPI
dotnet user-secrets set "ECGrid:ApiKey" "your-key-here"

Key Patterns

Application Setup and Client Registration (Program.cs)

// Program.cs — Minimal API setup with ECGrid HttpClient
var builder = WebApplication.CreateBuilder(args);

// Register a named client; the ECGrid API key is applied here, not in each handler
builder.Services.AddHttpClient("ecgrid", (sp, client) =>
{
var config = sp.GetRequiredService<IConfiguration>();
client.BaseAddress = new Uri(config["ECGrid:BaseUrl"]!);
// API key from IConfiguration — never exposed to the proxy's callers
client.DefaultRequestHeaders.Add("X-API-Key", config["ECGrid:ApiKey"]!);
});

var app = builder.Build();

Endpoint Registration

// GET /inbox — returns parcels waiting in the configured mailbox
app.MapGet("/inbox", async (IHttpClientFactory factory, IConfiguration config) =>
{
var http = factory.CreateClient("ecgrid");
var mailboxId = config.GetValue<int>("ECGrid:MailboxId");

var resp = await http.PostAsJsonAsync(
"v2/parcels/pending-inbox-list",
new { mailboxId, pageNo = 1, recordsPerPage = 25 });
var result = await resp.Content.ReadFromJsonAsync<ApiResponse<List<ParcelSummary>>>();

return Results.Ok(result?.Data ?? []);
});

// GET /parcel/{id} — downloads a single parcel's EDI content
app.MapGet("/parcel/{id:long}", async (long id, IHttpClientFactory factory) =>
{
var http = factory.CreateClient("ecgrid");
var response = await http.GetAsync($"/v2/parcels/{id}/download");

if (!response.IsSuccessStatusCode)
return Results.StatusCode((int)response.StatusCode);

var bytes = await response.Content.ReadAsByteArrayAsync();

// Confirm download so ECGrid marks the parcel as delivered
await http.PostAsync($"/v2/parcels/{id}/confirm", null);

return Results.File(bytes, "application/octet-stream", $"parcel-{id}.edi");
});

// POST /upload — accepts an EDI file and forwards it to ECGrid
app.MapPost("/upload", async (IFormFile file, IHttpClientFactory factory) =>
{
var http = factory.CreateClient("ecgrid");

using var ms = new MemoryStream();
await file.CopyToAsync(ms);

using var content = new ByteArrayContent(ms.ToArray());
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
content.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment") { FileName = file.FileName };

var response = await http.PostAsync("/v2/parcels/upload", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadFromJsonAsync<ApiResponse<ParcelUploadResult>>();
return Results.Ok(result?.Data);
});

app.Run();

Exposed Proxy Endpoints

MethodRouteDescription
GET/inboxLists parcels in the configured mailbox inbox
GET/parcel/{id}Downloads a parcel and confirms delivery
POST/uploadUploads a multipart EDI file to ECGrid

How to Run

cd samples/rest/ECGrid-REST-dotnet10-MinimalAPI
dotnet user-secrets set "ECGrid:ApiKey" "your-key-here"
dotnet run

The API will start on https://localhost:5001 (or as configured). Use a tool like curl or Postman to call the proxy endpoints.

# Example: check inbox
curl https://localhost:5001/inbox

See Also