Skip to content

tomas-pinto/StoryProvider

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

StoryProvider

A small ASP.NET Core Web API that returns the top n best stories ordered by score from an in-memory snapshot refreshed in the background.

Prerequisites

  • .NET 10 SDK

Run the application

dotnet restore
dotnet run --project .\src\StoryProvider.WebAPI\StoryProvider.WebAPI.csproj

By default the API listens on the local URLs shown by ASP.NET Core at startup.

With the included development launch settings, the app runs on:

  • http://localhost:5156
  • https://localhost:7031

OpenAPI and Swagger UI

In the Development environment the app exposes:

  • OpenAPI document: /openapi/v1.json
  • Swagger UI: /swagger

Examples:

  • http://localhost:5156/swagger
  • https://localhost:7031/swagger

Endpoint

GET /api/stories/best?n=10

Example response:

[
  {
	"title": "Example Hacker News story",
	"uri": "https://example.com/article",
	"postedBy": "johndoe",
	"time": "2025-01-15T09:30:00+00:00",
	"score": 245,
	"commentCount": 81
  },
  {
	"title": "Another top story",
	"uri": "https://example.com/another-article",
	"postedBy": "janedoe",
	"time": "2025-01-15T08:10:00+00:00",
	"score": 198,
	"commentCount": 54
  }
]

Configuration

The application is configured in src/StoryProvider.WebAPI/appsettings.json.

HackerNews

  • BaseUrl: the Hacker News API base URL
  • BestStoriesEndpoint: the upstream endpoint used to retrieve best story IDs
  • ItemEndpointFormat: the upstream endpoint template used to retrieve story details by ID
  • StoryCacheDurationSeconds: how long individual story details are cached in memory
  • MaxConcurrentRequests: the maximum number of concurrent upstream story-detail requests across the application

StoryProvider

  • MaxStoriesPerRequest: the maximum number of stories accepted per API request

StoryRefresh

  • RefreshIntervalSeconds: how often the background worker refreshes the snapshot
  • CacheLifetimeSeconds: how long the best stories are retained in the in-memory cache

Architecture overview

Project Purpose / intent
StoryProvider.WebAPI ASP.NET Core host that exposes the HTTP API, Swagger/OpenAPI, configuration binding, and DI composition root.
StoryProvider.Workers Background processing layer that decides when best-story snapshot refreshes run.
StoryProvider.Services Application use-case layer that refreshes and queries the cached best-story snapshot.
StoryProvider.Services.Abstractions Contracts for application services and shared response models used across layers.
StoryProvider.Models Shared internal models.
StoryProvider.Sources Provider adapter layer that validates and maps external story data into the internal story model.
StoryProvider.Sources.Abstractions Contracts and shared story model used by source adapters and services.
StoryProvider.Clients Low-level upstream HTTP client layer for talking to Hacker News.
StoryProvider.Clients.Abstractions Contracts and DTOs for upstream client communication.

Assumptions

  • The API exposes a single REST endpoint for the requested best stories scenario.
  • Stories without the required data for the response contract are skipped.
  • In-memory caching is sufficient for this exercise to reduce repeated upstream calls within one app instance.

Efficiency considerations

  • A background worker refreshes the best-stories cache so requests are served from memory.
  • The story cache is the only in-memory cache layer used by the application flow.
  • Outbound requests for story details are throttled with bounded concurrency through a SemaphoreSlim.

Future enhancements

  • Add static code analysis with SonarQube in the CI/CD pipeline.
  • Publish a versioned service artifact and Swagger/OpenAPI package to GitHub Releases from CI/CD.
  • Add file logging and decentralized logging integration.
  • Add distributed caching (e.g. Redis) for multi-instance deployments.
  • Add circuit breaker resilience policies for upstream dependencies (e.g. Polly).
  • Increase unit test coverage and add integration tests.
  • Add more story sources behind IStorySource.
  • Add pagination or streaming options for larger result sets (currently limiting n to a configurable value).
  • Add Dependency Injection specific project components to interface with WebApi.
  • Add a Better wrapper around caching layer
  • Add Exception filters and more tests around api call failure.

About

Simple C# Story Provider

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages