Services¶
In a Coalesce, you are fairly likely to end up with a need for some API endpoints that aren't closely tied with your regular data model. While you could stick static Methods on one of your entities, this solution just leads to a jumbled mess of functionality all over your data model that doesn't belong there.
Instead, Coalesce allows you to generate API Controllers and a TypeScript client from a service. A service, in this case, is nothing more than a C# class or an interface with methods on it, annotated with [Coalesce,Service]
. An implementation of this class or interface must be injectable from your application's service container, so a registration in Startup.cs is needed.
The instance methods of these services conform exactly to the specifications outlined in Methods with a few exceptions:
- TypeScript functions for invoking the endpoint have no
reload: boolean
parameter.- Instance methods don't operate on an instance of some model with a known key, but instead on an injected instance of the service.
Generated Code¶
For each external type found in your application's model, Coalesce will generate:
- An API controller with endpoints that correspond to the service's instance methods.
- A TypeScript client containing the members outlined in Methods for invoking these endpoints.
Example Service¶
An example of a service might look something like this:
[Coalesce, Service]
public interface IWeatherService
{
WeatherData GetWeather(string zipCode);
}
public class WeatherData
{
public double TempFahrenheit { get; set; }
// ... Other properties as desired
}
With an implementation:
public class WeatherService : IWeatherService
{
public WeatherService(AppDbContext db)
{
this.db = db;
}
public WeatherData GetWeather(string zipCode)
{
// Assuming some magic HttpGet method that works as follows...
var response = HttpGet("http://www.example.com/api/weather/" + zipCode);
return response.Body.SerializeTo<WeatherData>();
}
public void MethodThatIsntExposedBecauseItIsntOnTheExposedInterface() { }
}
And a registration:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddCoalesce<AppDbContext>();
services.AddScoped<IWeatherService, WeatherService>();
}
}
While it isn't required that an interface for your service exist - you can generate directly from the implementation, it is highly recommended that an interface be used. Interfaces increase testability and reduce risk of accidentally changing the signature of a published API, among other benefits.