Skip to main content

Overview

The PriceSignal backend is built with:
  • ASP.NET Core 8.0 - Web framework
  • HotChocolate 13.9 - GraphQL server implementation
  • Entity Framework Core 8.0 - ORM for database access
  • PostgreSQL - Primary database
  • WebSocket - Real-time price updates

Project Structure

The backend follows a clean architecture pattern:
src/
├── PriceSignal/      # Main web API project
├── Application/      # Application business logic
├── Domain/          # Domain entities and interfaces
└── Infrastructure/  # Data access and external services

PriceSignal (Web API)

Main entry point containing:
  • GraphQL schema and resolvers
  • API endpoints
  • Middleware configuration
  • SPA integration

Infrastructure

Data access and external integrations:
  • Entity Framework Core DbContext
  • Database migrations
  • External API clients (Binance, Alpaca)
  • WebSocket clients for real-time data

Key Dependencies

GraphQL (HotChocolate)

  • HotChocolate.AspNetCore (13.9.4) - GraphQL server
  • HotChocolate.AspNetCore.Authorization (13.9.4) - GraphQL authorization
  • HotChocolate.Data.EntityFramework (13.9.4) - EF Core integration
  • HotChocolate.PersistedQueries.InMemory (13.9.4) - Query persistence
  • HotChocolate.Types.Analyzers (13.9.4) - Code analyzers

Entity Framework Core

  • Microsoft.EntityFrameworkCore (8.0.4) - ORM framework
  • Npgsql.EntityFrameworkCore.PostgreSQL (8.0.4) - PostgreSQL provider
  • EFCore.NamingConventions (8.0.3) - Snake case naming

HTTP & WebSocket Clients

  • Refit (7.0.0) - Type-safe REST client
  • Websocket.Client (5.1.1) - WebSocket client
  • Microsoft.Extensions.Http.Polly (8.0.6) - Resilience and fault handling
  • Polly.Core (8.4.0) - Resilience policies

SPA Integration

  • Microsoft.AspNetCore.SpaServices.Extensions (8.0.5) - Serve React app

Development Commands

Running the Application

cd src/PriceSignal
dotnet watch
dotnet watch enables hot reload - changes to C# files will automatically rebuild and restart the application.

Database Migrations

dotnet ef migrations add MigrationName --project src/Infrastructure --startup-project src/PriceSignal
Always create migrations from the solution root directory and specify both the Infrastructure project (where migrations live) and PriceSignal project (startup project with configuration).

Development Workflow

1

Start the Development Server

cd src/PriceSignal
dotnet watch
The application will start and listen on the configured ports (typically 5000 for HTTP, 5001 for HTTPS).
2

Access GraphQL Playground

Navigate to http://localhost:5000/graphql to access Banana Cake Pop, the GraphQL IDE provided by HotChocolate.
3

Make Code Changes

Edit files in the src/ directories. The dotnet watch command will detect changes and automatically rebuild and restart the application.
4

Test Your Changes

Use the GraphQL playground to test queries, mutations, and subscriptions.

GraphQL Schema

PriceSignal uses HotChocolate’s code-first approach to define the GraphQL schema.

Schema Features

  • Queries - Fetch cryptocurrency prices, user alerts, and settings
  • Mutations - Create, update, delete alerts and user preferences
  • Subscriptions - Real-time price updates via WebSocket
  • Authorization - Firebase authentication integration

Adding New Queries

  1. Create a query class or add to existing query type
  2. Decorate with HotChocolate attributes
  3. Use dependency injection for services
  4. Return strongly-typed results

Adding New Mutations

  1. Create input and payload types
  2. Define mutation method
  3. Implement business logic
  4. Return success/error payload

Adding New Subscriptions

  1. Define subscription resolver
  2. Use ITopicEventReceiver for event streaming
  3. Publish events from mutations or background services

Database Access

DbContext

The ApplicationDbContext is located in the Infrastructure project and defines:
  • Entity configurations
  • Database schema
  • Relationships

Creating Entities

  1. Define entity in Domain project
  2. Configure in ApplicationDbContext
  3. Create migration
  4. Apply migration to database

Querying Data

Use Entity Framework Core with HotChocolate’s data integration:
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<Price> GetPrices([Service] ApplicationDbContext context)
    => context.Prices;

External Integrations

Binance Integration

Configuration in appsettings.json:
"Binance": {
  "WebsocketUrl": "wss://stream.binance.com:9443/stream?streams=btcusdt@aggTrade/ethusdt@aggTrade",
  "ApiUrl": "https://api.binance.com",
  "Enabled": "true"
}
Provides:
  • Real-time price data via WebSocket
  • Historical data via REST API

Alpaca Markets Integration

Configuration in appsettings.json:
"Alpaca": {
  "ApiUrl": "https://data.alpaca.markets"
}
Provides:
  • Cryptocurrency market data
  • Price history and OHLCV data

Configuration

Application Settings

The appsettings.json file contains:
  • Logging - Configure log levels
  • AllowedHosts - CORS configuration
  • ConnectionStrings - Database connections
  • External APIs - Binance, Alpaca configuration

User Secrets (Development)

Store sensitive configuration in user secrets:
cd src/PriceSignal
dotnet user-secrets set "ConnectionStrings:DefaultConnection" "your-connection-string"
dotnet user-secrets set "Firebase:ApiKey" "your-firebase-key"

Environment Variables

For production deployments, use environment variables:
export ConnectionStrings__DefaultConnection="your-connection-string"
export Binance__Enabled="true"

Testing

Running Tests

dotnet test

Writing Tests

Create test projects for:
  • Unit tests for business logic
  • Integration tests for API endpoints
  • GraphQL query/mutation tests

Building for Production

1

Build Frontend

cd src/react-app
npm run build
This builds the React app and outputs to dist/.
2

Copy Frontend to wwwroot

The build process should copy files from dist/ to src/PriceSignal/wwwroot/.
3

Build Backend

cd src/PriceSignal
dotnet publish -c Release -o out
4

Run Production Build

cd out
dotnet PriceSignal.dll

Docker Support

The project includes Docker support (DockerDefaultTargetOS is set to Linux).

Building Docker Image

docker build -t pricesignal .

Running with Docker Compose

docker-compose up
Ensure your docker-compose.yml includes PostgreSQL service and proper environment variables for the connection string.

Common Tasks

Adding a New External API Client

  1. Define interface in Application layer
  2. Implement using Refit in Infrastructure
  3. Configure HTTP client with Polly policies
  4. Register in dependency injection

Adding a New Background Service

  1. Create class implementing BackgroundService
  2. Implement ExecuteAsync method
  3. Register in Program.cs

Implementing Real-time Updates

  1. Define subscription in GraphQL schema
  2. Create background service to monitor data source
  3. Publish events using ITopicEventSender
  4. Subscribe from frontend using GraphQL subscriptions

Troubleshooting

Port Already in Use

Change ports in Properties/launchSettings.json or use environment variables:
export ASPNETCORE_URLS="http://localhost:5050"

Database Connection Issues

Verify:
  1. PostgreSQL is running
  2. Connection string is correct
  3. Database exists
  4. User has proper permissions

Migration Errors

If migrations fail:
  1. Ensure PostgreSQL is running
  2. Check connection string
  3. Verify Infrastructure project builds successfully
  4. Try removing and recreating the migration

Next Steps

Build docs developers (and LLMs) love