Swagger with Dropwizard APIs that use Generic types - swagger

I have a generic response object in my Dropwizard API with Response which is a wrapper containing a status enum and a value. The API operations have a reponse like Response or Response>.
I have been trying to find a way to handle this and saw some mentions that this is handled for Spring Rest / Swagger?
I am using:
com.wordnik
swagger-jaxrs_2.10
1.3.5
Has anyone resolved this in a nice generic way?

I think you might be looking for something like this:
#GET
#Path("/pets")
#ApiOperation(value = "Get all pets.", response = Pet.class)
public Response<List<Pet>> getPets() {
...
}

Came around this old question as I was looking for a solution for the same issue.
Here is my workaround :
Create a wrapper class :
#ApiModel
public class PetListResponse extends Response<List<Pet>> {
#Override
#ApiModelProperty
public List<Pet> getValue() {
return super.getValue()
}
}
Override the response in the API :
#GET
#Path("/pets")
#ApiOperation(value = "Get all pets.", response = PetListResponse.class)
public Response<List<Pet>> getPets() {
...
}
Success :)

Related

Best way to add a RequestInterceptor to a single FeignClient

I need to add a RequestInterceptor to a specific feign client. The interceptor will add auth information that I do not want to leak to a third party, hence I do not want it to trigger for ALL Feign clients. I have this working, but this seems a tad messy, and am hoping there is a cleaner (less code) option.
I am hoping someone can point to where I can simplify things. Particularly around the encoder/decoder stuff. I really dislike them cluttering up my services constructor like that and find it odd that they even need to be specified in the first place.
I have
// build.gradle
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
I have a RequestInterceptor as
import feign.RequestInterceptor;
import feign.RequestTemplate;
public class BearerAuthRequestInterceptor implements RequestInterceptor {
#Override
public void apply(RequestTemplate requestTemplate) {
// ... SNIP ... (just adds an Authorization header)
}
}
I have a FeignClient as
#FeignClient(name = "myfeignclient")
public interface MyFeignClient {
#GetMapping(value = "/doTheThing")
String doTheThing();
}
I use my FeignClient from a service like so:
#Service
#Import(FeignClientsConfiguration.class)
public class MyService {
private final MyFeignClient myFeignClient;
#Autowired
public MyService(Decoder decoder, Encoder encoder, Contract contract) {
this.myFeignClient = Feign.builder()
.contract(contract)
.encoder(encoder)
.decoder(decoder)
.requestInterceptor(new BearerAuthRequestInterceptor())
.target(MyFeignClient.class, "https://whatever.com");
}
public void callTheFeignClient() {
myFeignClient.doTheThing();
}
}
Thanks to this comment, I managed to tidy up my implementation a little bit. So no more need for specifying encode/decoder nonsense, or having to manually build my Feign client.
The docs here provide some info, but as is typical they are a bit thin on concrete examples, so perhaps the below will help someone else. Note: I'm using spring boot, and including feign like so in build.gradle implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
First, create the RequestInterceptor like so:
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.jwt.Jwt;
import feign.RequestInterceptor;
import lombok.extern.slf4j.Slf4j;
/**
* A Feign configuration to add the incoming Bearer token to an outgoing feign client request.
* Only annotate this class with "#Configuration" if you want this interceptor to apply globally to all your Feign clients.
* Otherwise you risk exposing the auth token to a third party, or adding it unnecessarily to requests that don't need it.
*/
#Slf4j
public class BearerAuthFeignConfig {
#Bean
public RequestInterceptor bearerAuthRequestInterceptor() {
return requestTemplate -> {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.getPrincipal() instanceof Jwt) {
Jwt jwt = (Jwt) authentication.getPrincipal();
requestTemplate.header("Authorization", "Bearer " + jwt.getTokenValue());
} else {
log.error("Unable to add Authoriation header to Feign requestTemplate");
}
};
}
}
Then when declaring your feign client, pass the configuration
#FeignClient(
name = "my-client-that-needs-the-auth",
configuration = BearerAuthFeignConfig.class,
url = "http://whatever.com"
)
public interface PlayerManagementClient {
...
You'll also need the #EnableFeignClients annotation on your #SpringBootApplication class

How to use get keyword as a class instance method name?

I know that get is one of the keywords in Dart, but I wanna wrap an HTTP client class with an instance method named get in my flutter app, it's semantic。 How can I do this?
Works for me:
void main() {
Http().get('');
}
class Http {
String get(String list) {
print('get called');
}
}
Maybe this will help
class HttpClient {
HttpClient.get() {
...
}
}

Calling injected services from class instances

I'm writing an Angular2 app. Consider a class Cat which I instantiate many instances of, which has an API method to write itself out:
class Cat {
constructor(private name: string) { }
public write() {
Api.write(this); // <== how do I do this?
}
}
The Cat#write method needs to access an API service wrapped around Http:
#Injectable()
class Api {
constructor(private http: Http) { }
write(data) {
this.http.post(...);
}
}
The (perhaps trivially simple) problem I have is how to access API#write from within my Cat class. Since I need the Cat constructor to pass in the name, I can't use it for injection. So how do I make the API#write available to it? Is there some way to access the singleton instance of Api? In that case, who would be in charge of instantiating the singleton instance?
I played around with a static API class but this obviously doesn't work, since injection is into instances, not static classes.
What basic design pattern am I missing here?
I've been struggling with this for a while as well. I did come up with sort of a solution, but it feels hacky.
I use a singleton AppInjector instance. It is set only once, in the constructor of AppComponent (the bootstrapped component). It is used to resolve dependencies for objects to create.
This AppInjector looks something like this:
export class AppInjector {
private static _INJECTOR: Injector;
public static set INSTANCE(injector: Injector) {
if (!this._INJECTOR) {
this._INJECTOR = injector;
}
}
public static get INSTANCE() : Injector {
return this._INJECTOR;
}
}
And the contructor of the AppComponent looks like this:
constructor(injector: Injector) {
AppInjector.INSTANCE = injector;
}
Now if you have added your Api in the bootstrap function of your application:
bootstrap(AppComponent, [Api]);
You will be able to get this singleton from within the Cat instance like this:
class Cat {
public get _api() : Api {
return AppInjector.INSTANCE.get(Api);
}
constructor(private name: string) { }
public write() {
this._api.write(this);
}
}
Again, this by no means feels like the right solution, and probably against a lot of guidelines in Angular2, but I understand your problem, and would also like a better solution than this, but it works fine now for as it is, and I can happily continue coding

Jersey 2 per-request #Context injection

Overview
In Jersey 2, can I inject a custom, request-specific value into my resource? Specifically, I would like to inject a MyThing which can be derived from my custom security context MySecurityContext. I would like to inject MyThing directly to make the code clean.
Is there any way to do this? According to this question it can't be done using a ContextResolver although this article and this example suggest it might be possible.
What Works
Using an auth filter, I am able to set my custom security context using code like this:
#Provider
public class HttpTokenAuthFilter implements IComposableJaxRsAuthFilter {
#Override
public boolean doAuth(ContainerRequestContext requestContext) throws WebApplicationException {
// error handling omitted
requestContext.setSecurityContext(MySecurityContext.fromHeaders(requestContext));
}
}
... and then in my resource I can pull a value from it:
#Path("/foo")
public class MyResource {
#Context
private SecurityContext securityContext;
#Get
public String doGetFoo() {
MyThing myThing = ((MySecurityContext)securityContext).getThing();
// use myThing to produce a result
}
Where I'm Stuck
... however, since this is going to be repeated a lot, I would much rather just write:
#Context
private MyThing myThing;
I tried defining a ContextResolver. I see it getting constructed, but I never see it getting invoked, so I have not yet tried any of the techniques linked above. Is this even the correct class to be using?
#Provider
public class MyThingResolver implements ContextResolver<MyThing> {
public MyThingResolver() {
System.out.println("ctor");
}
#Override
public MyThing getContext(Class type) {
System.out.println("getContext");
if (type.equals(MyThing.class)) {
return new MyThing(); // TODO: SHOULD ACTUALLY USE CURRENT MySession
}
return null;
}
}
Almost the solution
Per this answer and the refinements specified at this followup, it's almost possible to accomplish the injection using a Factory. The only caveat is, you must inject MyThing via a Provider, otherwise it's going to get created (with the default SecurityContext) before the filter runs and swaps in the MySecurityContext.
The factory code looks like this:
public class MyThingFactory implements Factory<MyThing> {
#Context
private SecurityContext securityContext;
#Override
public MyThing provide() {
return ((MySecurityContext)securityContext).getThing();
}
#Override
public void dispose(MyThing session) {
}
}
The resource can then inject it like this:
#Context
private Provider<MyThing> myThingProvider;
... and consume it like this:
MyThing myThing = myThingProvider.get();
// use myThing
The factory registration in the AbstractBinder looks like this:
this.bindFactory(MyThingFactory.class) //
.to(MyThing.class) //
.in(RequestScoped.class);
(Edit) Proxies to the Rescue!
Per the comment from #peeskillet, it is possible to get rid of the Provider by proxying MyThing. (Per # jwells131313, MyThing must therefore be an interface or a proxy-able class.)
The binding then looks like this:
this.bindFactory(MyThingFactory.class) //
.to(MyThing.class) //
.proxy(true) //
.in(RequestScoped.class);
and injection finally works as desired:
#Context
private MyThing myThing;

AutoFac Register confusion

Hi I am just been looking at AutoFac and following their getting-started tutorial
http://autofac.readthedocs.org/en/latest/getting-started/index.html
having followed it and understanding how their services work I wanted to try to create a new implementation on the same interface type
builder.RegisterType<TodayWriter>().As<IDateWriter>();
builder.RegisterType<TomorrowWriter>().As<IDateWriter>();
Both implentations contain the same code
public class TomorrowWriter : IDateWriter
{
private IOutput _output;
public TomorrowWriter(IOutput output)
{
this._output = output;
}
public void WriteDate()
{
this._output.Write(DateTime.Today.AddDays(1).ToShortDateString());
}
}
So TodaysWriter is the same apart from the WriteDate method displaying
this._output.Write(DateTime.Today.ToShortDateString());
instead.
So now using the application, how do I determine what implementation to use as both methods are called WriteDate()
using(var scope = Container.BeginLifetimeScope())
{
var writer = scope.Resolve<IDateWriter>();
// Is this using todaysWriter or TomorrowWriter?
writer.WriteDate();
}
Am I using this wrong?
Thanks
To differentiate between different implementations of the same interface look at named and keyed services in the docs.
Alternatively you can roll your own by registering a DateWriterFactory and having a method on that to get a specific IDateWriter implementation. something like:
public class DateWriterFactory
{
IDateWriter GetWriter(string writerName)
{
if (writername=="TodayWriter")
return new TodayWriter();
if (writername=="TomorrowWriter")
return new TomorrowWriter();
}
}
obviously the implementation of the factory could be as complex or as simple as you need. Or you could just have methods to get the fixed writers rather than pass in a string.

Resources