Silky Microservice FrameworkSilky Microservice Framework
Home
Docs
Config
Source
github
gitee
  • 简体中文
  • English
Home
Docs
Config
Source
github
gitee
  • 简体中文
  • English
  • Introduction

    • Silky Framework Overview
  • Getting Started

    • Glossary
    • Quick Start
    • Project Template
    • Microservice Architecture
    • Sample Projects
  • Host & Module

    • Host Types
    • Gateway Configuration
    • Module System
    • Plugin System
  • Gateway & HTTP

    • Swagger / OpenAPI
    • MiniProfiler
    • CORS
    • Audit Logging
  • Service & RPC

    • App Services & Service Entries
    • RPC Communication
    • WebSocket
    • Service Registry
    • Service Governance
  • Data & Cache

    • EFCore Data Access
    • Caching
    • Distributed Lock
  • Security & Auth

    • Identity & Authentication
    • Distributed Transactions
  • Infrastructure

    • Dependency Injection
    • Object Mapping
    • Validation
    • Link Tracking (SkyAPM)
    • Logging (Serilog)
    • Health Checks
    • Message Bus (MassTransit)
    • Unit & Integration Testing

Service Definition

A service interface is the basic unit for defining services in a Silky microservice. The interface can be referenced by other microservices, which communicate with its provider via the RPC framework.

Annotate any C# interface with [ServiceRoute] to make it an application service interface:

namespace Demo.Contracts;

[ServiceRoute]
public interface IOrderAppService
{
    Task<string> Echo(string ping);
}

By convention, the recommended naming pattern is:

  • Interface: IXxxxAppService → default route template: api/{appservice} (e.g. api/order)
  • Implementation: XxxxAppService

The route template can be customized:

[ServiceRoute("{appservice=customName}")]
public interface IOrderAppService { }
PropertyDescriptionDefault
templateRoute template for the service. Use {appservice=name} to set a custom nameapi/{appservice}

Service Entries

A Service Entry is generated for every method defined on a service interface. In Silky, a service entry is analogous to an MVC Action, and the application service is analogous to a Controller.

Each service entry has a corresponding Service Entry ID that uniquely identifies it within the cluster. During RPC communication, a service entry can be located by its ID or by its WebAPI + HTTP verb.

Service Entry ID

ServiceEntryId = FullyQualifiedMethodName + ParameterNames + _ + HttpVerb

Example — the Echo(string ping) method generates:

Test.ITestAppService.Echo.ping_Get

You can view service entry IDs and their configuration in the built-in Dashboard (accessible via the gateway).

Generating WebAPI from Service Entries

When a service interface is referenced by a Web Host or Gateway, Silky generates RESTful WebAPI endpoints based on the interface route template and the HTTP verb attributes on each method.

Rules:

  1. [ProhibitExtranet] (or [Governance(ProhibitExtranet = true)]) prevents the endpoint from being accessed externally.
  2. [ServiceRoute("{appservice=name}")] sets a custom route prefix for the interface.
  3. The HTTP verb is determined by [HttpGet], [HttpPost], [HttpPut], [HttpDelete] attributes; the default is inferred from the method name prefix (Get, Create, Update, Delete).
[ServiceRoute]
public interface IOrderAppService
{
    // GET api/order/{id}
    [HttpGet("{id}")]
    Task<OrderOutput> GetAsync(long id);

    // POST api/order
    [HttpPost]
    Task<OrderOutput> CreateAsync(CreateOrderInput input);

    // PUT api/order/{id}
    [HttpPut("{id}")]
    Task<OrderOutput> UpdateAsync(long id, UpdateOrderInput input);

    // DELETE api/order/{id}
    [HttpDelete("{id}")]
    Task DeleteAsync(long id);

    // Not exposed externally (RPC only)
    [ProhibitExtranet]
    Task<OrderOutput> GetInternalAsync(long id);
}

Governance Attribute

Use [Governance] on any service entry method to override the global governance configuration:

[HttpGet("{name}")]
[Governance(ShuntStrategy = ShuntStrategy.HashAlgorithm)]
Task<TestOut> Get([HashKey] string name);
PropertyDescription
ShuntStrategyLoad balancing strategy: Polling, Random, HashAlgorithm
TimeoutMillSecondsRPC timeout in milliseconds
RetryTimesNumber of retry attempts on failure
EnableCircuitBreakerEnable/disable circuit breaking
ProhibitExtranetBlock external (HTTP gateway) access
MaxConcurrentHandlingCountMax concurrent RPC requests per instance

Fallback

Define a fallback implementation for graceful degradation when the remote call fails:

[ServiceRoute]
[Fallback(typeof(OrderAppServiceFallback))]
public interface IOrderAppService
{
    Task<OrderOutput> GetAsync(long id);
}

// Fallback implementation
public class OrderAppServiceFallback : IOrderAppService
{
    public Task<OrderOutput> GetAsync(long id)
    {
        // Return a safe default when the remote call fails
        return Task.FromResult(new OrderOutput { Id = id, Status = "Unavailable" });
    }
}

Service Implementation

Implement the interface in the microservice host project. Silky auto-registers implementations via convention:

// Register as Scoped (one instance per request)
public class OrderAppService : IOrderAppService, IScopedDependency
{
    private readonly IOrderRepository _orderRepository;

    public OrderAppService(IOrderRepository orderRepository)
    {
        _orderRepository = orderRepository;
    }

    public async Task<OrderOutput> GetAsync(long id)
    {
        var order = await _orderRepository.GetAsync(id);
        return order.MapTo<OrderOutput>();
    }
}

Supported DI lifetimes via marker interfaces:

  • ISingletonDependency — singleton
  • IScopedDependency — scoped (one per request)
  • ITransientDependency — transient (new instance each time)
Edit this page
Next
RPC Communication