Return simple raw string in ServiceStack (.NET) - servicestack

For our internal monitoring, our dev ops team asked us to provide a simple endpoint for the bot to hit. Something like: www.domain.com/monitor/check
If everything is fine, it should return a raw string, something like "GoodToGo"
We have an app currently using ServiceStack and it works fine, but I'm having trouble adding this simple endpoint. Any help would be appreciated. This is what I have, and it's having trouble finding the route for my "service."
public class InternalService : Service
{
public class EmptyRequest {}
[Route("/monitor/check", "")]
public object Get(EmptyRequest request)
{
return "GoodToGo";
}
}

The [Route] attribute should be on the Request DTO, i.e:
[Route("/monitor/check")]
public class EmptyRequest : IReturn<string> {}
public class InternalService : Service
{
public object Get(EmptyRequest request)
{
return "GoodToGo";
}
}

Related

Why does ServiceStack burden the DTOs with routing concerns?

I'm learning ServiceStack, and from reading this page, a couple of things aren't clear to me.
So, considering this DTO pair:
[Route("/hello")]
[Route("/hello/{Name}")]
public class Hello : IReturn<HelloResponse>
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
And this service:
public class MyService : Service
{
public object Any(Hello request)
{
return new HelloResponse { Result = $"Hello, {request.Name}!" };
}
}
Why is it the responsibility of Hello to specify the return-type using the marker interface IReturn<HelloResponse>?
It seems like this could be inferred from the return-type of MyService - except that it's conventional to use a return-type of object, which also requires type-casts in tests and client-code. Why?
And why are the Route attributes applied to the model Hello, rather than to the service MyService, where the request is actually handled?
It seems like both of these facts are more relevant to the service than to the model.
For one, a person reading the service declaration would more readily find the information pertaining to the service, instead of having to find it in the model.
For another, accepted HTTP methods are implicitly declared by the service via method-naming conventions - so it seems like the facts about service routing/dispatch are sort of scattered between two layers.
From that point of view, I was probably expecting something more along the lines of this:
// NON-VALID EXAMPLE
public class Hello
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
public class MyService : Service
{
[Route("/hello")]
[Route("/hello/{Name}")]
public HelloResponse Any(Hello request)
{
return new HelloResponse { Result = $"Hello, {request.Name}!" };
}
}
What is the reason or the design thinking behind the conventions?
(Please don't take this as merely an attempt at critique - there's a lot of things I enjoy about this framework, and I am genuinely trying to understand the thinking behind these conventions.)
Why does ServiceStack burden the DTOs with routing concerns?
Note no routing concern burden is required at all in ServiceStack and all user-defined Routes are optional where all clients are able to call Services utilizing their automatic pre-defined routes.
Why is it the responsibility of Hello to specify the return-type using the marker interface IReturn?
It provides better typed access for client libraries like the generic C#/.NET Service Clients who are able to re-use the existing SericeModel DTOs to enable its optimal typed API without any code-gen, e.g:
var client = new JsonServiceClient(baseUrl);
var response = client.Get(new Hello { Name = "World" });
Or if you're not sharing DTOs it's also useful for Add ServiceStack Reference generated clients as well.
The return type on your Service implementation is meaningless in ServiceStack, i.e. has no behavioral difference, and would prevent the same Service implementation from returning the same Response DTO, or decorated with a custom HTTP Response, e.g:
public object Any(Hello request)
{
return new HelloResponse { Result = $"Hello, {request.Name}!" };
//...
return new HttpResult(new HelloResponse { Result = $"Hello, {request.Name}!" }) {
//... custom
};
}
both return types adhere to the API's IReturn<HelloResponse> contract
It's only useful for calling inter-process Services using the older ResolveService method, but for inter-prcess requests it's recommended to use the Service Gateway instead which also utilizes the type IReturn<T> interface markers for its Typed APIs.
The routes are not an implementation detail, they're apart of your public Service Contract and should be annotated on your DTOs which are used to define your Service Contract.
[Route("/hello")]
[Route("/hello/{Name}")]
public class Hello : IReturn<HelloResponse>
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
Where they're used by the .NET ServiceStack Clients to send Service Client Requests.
var response = client.Get(new Hello { Name = "World" });
For another, accepted HTTP methods are implicitly declared by the service via method-naming conventions - so it seems like the facts about service routing/dispatch are sort of scattered between two layers.
Please see docs on Routing, the Route definition defines which methods the specific route is active on whilst the most appropriate Service implementation is invoked depending on the Request, e.g:
public object GetJson(Customers request) => ... // ONLY GET JSON Requests
public object Get(Customers request) => ... // All other GET Requests
public object Post(Customers request) => ... // ONLY POST Requests
public object Any(Customers request) => ... // ALL other Requests
What is the reason or the design thinking behind the conventions?
A lot of these issues is trying to blur the explicit typed Service Contract of your APIs and its concrete implementation, in ServiceStack these are distinct explicit concepts where all the information about your public Service Contract should be maintained in your implementation-free ServiceModel project.
Please read the Background Concepts docs to familiarize yourself with ServiceStack's purpose and goals.

Setting proper Unity Container configuration for resolving interface-class in decorator pattern

Given below are my different class declarations and how I am trying to setup unity container configuration to get a Interface to Concrete class implementation. The code currently throws either an stackoverflow exception or suggests that a interface cannot be constructed.
Please help me fix, either the class structure or the container configuration.
CodesController Class -
public class CodesController : ApiController
{
private readonly IUnitOfWorkAsync unitOfWork;
private readonly ICodeRepository repository;
public CodesController(IUnitOfWorkAsync unitOfWork, ICodeRepository codeRepository)
{
if (unitOfWork == null)
{
throw new ArgumentNullException("unitOfWork");
}
this.unitOfWork = unitOfWork;
this.repository = codeRepository;
}
//Other class level methods here
}
CodeRepository class -
public class CodeRepository : ICodeRepository
{
private readonly ICodeRepository codeRepository;
public CodeRepository(ICodeRepository repository)
{
this.codeRepository = repository;
}
public virtual async Task<IEnumerable<Code>> GetCodeAsync(string codeKey)
{ //Some implementation here}
}
ICodeRepository Interface -
public interface ICodeRepository : IRepositoryAsync<Code>
{
Task<IEnumerable<Code>> GetCodeAsync(string codeKey);
}
IRepositoryAsync Interface -
public interface IRepositoryAsync<TEntity> : IRepository<TEntity> where TEntity : class, IPersistenceHint
{
Task<bool> DeleteAsync(params object[] keyValues);
Task<bool> DeleteAsync(CancellationToken cancellationToken, params object[] keyValues);
Task<TEntity> FindAsync(params object[] keyValues);
Task<TEntity> FindAsync(CancellationToken cancellationToken, params object[] keyValues);
}
Unity Container Configuration-
container.RegisterType<IUnitOfWorkAsync, UnitOfWork>(
"test",
new TransientLifetimeManager(),
new InjectionConstructor(container.Resolve<IDataContextAsync>("test")));
container.RegisterType<ICodeRepository, CodeRepository>();
container.RegisterType<CodesController, CodesController>();
With this given configuration and class structure, based on my experimentation with container config, I get following exception -
JSON
exceptionMessage=An error occurred when trying to create a controller of type 'CodesController'. Make sure that the controller has a parameterless public constructor.
exceptionType=System.InvalidOperationException
innerException
exceptionMessage=Type '<Namespace>.Api.Controllers.CodesController' does not have a default constructor
stackTrace= at System.Linq.Expressions.Expression.New(Type type)
at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
Please suggest, if anything is wrong here, so that I can fix the same. Already struggling many days on this.
You're injecting ICodeRepository to CodeRepository, which probably causes to stackoverflow exception, since it will keep generating ICodeRepositories. It will generate a recursive call. Somewhat like this one:
public class BaseFoo
{
public BaseFoo(BaseFoo foo){ }
}
public class Foo : BaseFoo
{
public Foo() : base(new Foo()) { }
}
And regarding the "does not have a default constructor"-exception, have you registered a DependencyResolver for Web API? See one of these questions for more detailed information how to do it:
Using Unity with Web Api 2 gives error does not have a default constructor
Unity.WebApi | Make sure that the controller has a parameterless public constructor
ASP.Net MVC 4 Web API controller dosn't work with Unity.WebApi
As a side note, you shouldn't have to register the CodesController in your unity registration.

ServiceStack.Funq.Quartz cannot instantiating type?

ServiceStack.Funq.Quartz Sample Code is
public class MyServices : Service
{
public object Any(Hello request)
{
return new HelloResponse { Result = "Hello, {0}!".Fmt(request.Name) };
}
}
public class HelloJob : IJob
{
private MyServices MyServices { get; set; }
public HelloJob(MyServices myServices)
{
MyServices = myServices;
}
public void Execute(IJobExecutionContext context)
{
var response = MyServices.Any(new ServiceModel.Hello
{
Name = "CodeRevver"
});
response.PrintDump();
}
}
The above is works fine. if I in the MyServices Class, removed the Any function, and comment the Execute inner code.
public class MyServices : Service
{
}
the quartz.net will get the error:
[Quartz.Core.ErrorLogger】 An error occurred instantiating job to be executed. job= 'JobGroup1.GetUserJob111' Problem instantiating type 'ServiceStackWithQuartz.HelloJob'
why the class must have public object Any(Hello request) function ?
Thanks for using the package – I had no idea that other people would find it useful.
So If I understand correctly, in your situation you have:
public class MyServices : Service
{
}
And you’re trying to resolve this Service via constructor injection, which is effectively doing a:
container.Resolve<MyServices>();
This will fail because of the way the ServiceStack Funq IoC works. You can’t resolve a ServiceStack Service that has nothing in it (you'd probably never want to either) – It has to at least have one service implementation, It doesn’t matter what the implementation is.
Also, if you want to improve ServiceStack.Funq.Quartz, feel free to contribute to the code base.
Edit: It's probably worth mentioning that you can inject a "Non-Service" class with your logic in it if you want. You can resolve other classes that aren't based off of ServiceStack.Service even if there's nothing in them.
Edit 2: Responding to your "Service wont dispose" problem. This is the same across ServiceStack and has nothing to do with your Quartz Job. If you call a:
container.Resolve<MyServices>().Any(new new ServiceModel.Hello { });
from AppHost for example, your service wont dispose by itself. If you want it to dispose you can wrap it in a using statement. e.g.
using (var service = MyServices)
{
var response = MyServices.Any(new ServiceModel.Hello { });
}
The using will ensure that your service will be disposed afterwards.
Alternatively you can add the interface "IDispose" on to your Quartz Job and implement a Dispose() method that will do a:
MyServices.Dispose();
This will be called after a job has executed.

Approach on mocking ServiceStack service being called by another ServiceStack service

Let's say we have a situation where a service would call other services in ServiceStack.
From reading around, this is how one would call another service:
public class CompanyService : Service
{
public SetupCompanyResponse Any(SetupCompany request)
{
var employeeService = base.ResolveService<EmployeeService>();
// Do something with employeeService
var response = employeeService.Any(new SetupEmployees());
return new SetupCompanyResponse { NumOfEmployeesCreated = response.Count };
}
}
Question: How do I mock EmployeeService if I'm unit-testing CompanyService?
Easiest way I could think of is to generate an IEmployeeService interface so that it's easily mockable. However I'm not sure if base.ResolveService<T> will be able to properly resolve and auto-wire a ServiceStack service, given its interface instead, like so:
var employeeService = base.ResolveService<IEmployeeService>();
Especially when we are registering services this way (which I assume is configuring the object resolution based on concrete class, and not the interface e.g IEmployeeService)
public HelloAppHost() : base("Hello Web Services", typeof(HelloService).Assembly) { }
Update:
Apparently I'm able to somewhat achieve this simply by:
1) Registering the service interface with its implementation
public static void SetupServices(Container container)
{
container.RegisterAs<EmployeeService, IEmployeeService>();
}
2) Using the same exact code to resolve, except now I pass in the interface. The service is successfully resolved.
var employeeService = base.ResolveService<IEmployeeService>();
3) All I need to do now is to override the resolver, and the service dependency should be totally mockable.
Question: Is this also a valid approach? Why or why not?
ServiceStack's Service class resolves all its dependencies from an IResolver, defined by:
public interface IResolver
{
T TryResolve<T>();
}
This can be injected in ServiceStack's Service class in an number of ways as seen by the implementation:
public class Service : IService, IServiceBase, IDisposable
{
public static IResolver GlobalResolver { get; set; }
private IResolver resolver;
public virtual IResolver GetResolver()
{
return resolver ?? GlobalResolver;
}
public virtual Service SetResolver(IResolver resolver)
{
this.resolver = resolver;
return this;
}
public virtual T TryResolve<T>()
{
return this.GetResolver() == null
? default(T)
: this.GetResolver().TryResolve<T>();
}
...
}
Which you can use to control how Services resolve dependencies.
An easy way to unit test Services is to use a BasicAppHost as seen on the Testing wiki, i.e:
appHost = new BasicAppHost().Init();
var container = appHost.Container;
container.Register<IDbConnectionFactory>(
new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider));
container.RegisterAutoWired<CompanyService>();
container.RegisterAutoWiredAs<StubEmployeeService, EmployeeService>();
Where StubEmployeeService is your stub implementation of EmployeeService, e.g:
public class StubEmployeeService : EmployeeService
{
public SetupEmployeesResponse Any(SetupEmployees request)
{
return new SetupEmployeesResponse { ... };
}
}
You can also register Services using any of the registration methods ServiceStack's IOC Supports if you prefer to use your own mocking library.

ServiceStack - Empty Request Classes?

I have a question regarding ServiceStack. Why are there empty Request Classes, why do we have to have a Request Class? For example:
[Route("/test", "GET")]
public class Test
{
}
public class TestResponse
{
public string Date { get; set; }
}
public class TestService : Service
{
public object Get(Test test)
{
return new TestResponse { Date = DateTime.Now.ToString() };
}
}
If I don't pass an object with my request, my service fails?
Then I'm my Global.asax file, I have:
public class AxDataAppHost : AppHostBase
{
public AxDataAppHost() :
base("AxData", typeof(TestService).Assembly)
{
}
}
What if I have more than 1 service, in the example above I'm using TestService but what if I have one for Customers, Orders and Products? How do I handle multiple services?
why do we have to have a Request Class?
ServiceStack is a message-based framework that embraces Martin Fowler's Remote Service Best Practices (i.e. Remote Facade, DTOs and Gateway) which utilizes a ServiceGateway to send coarse-grained Request DTOs which commonly returns a typed Response DTO (though services can return anything). Using a message-based design has many advantages and is what enables ServiceStack's typed end-to-end API.
E.g. you can re-use these types you defined your services with:
public class Test : IReturn<TestResponse> {}
public class TestResponse
{
public string Date { get; set; }
}
On the client, which is what gives you a typed API without code-gen, e.g:
var client = new JsonServiceClient(BaseUri);
TestResponse response = client.Get(new Test());
Note: you don't even need custom routes as by default ServiceStack's C# clients will fallback to use the pre-defined routes (enabled by default).
What if I have more than 1 service, in the example above I'm using TestService but what if I have one for Customers, Orders and Products? How do I handle multiple services?
In your AppHost base constructor you're passing in an assembly (i.e. NOT a single service):
public AxDataAppHost() : base("AxData", typeof(TestService).Assembly) {}
This tells ServiceStack where to look for and wire-up all your services. You only need to do this once for each dll/assembly that your services are in.
ServiceStack's AppHosts also allows specifying multiple assemblies which you can use to wire-up services located in multiple assemblies, e.g:
public AxDataAppHost()
: base("AxData", typeof(TestService).Assembly, typeof(ServiceInNewDll).Assembly) {}

Resources