Inherit interface resolvers in Apollo Federation - apollo

Is there a way to use interface resolver inheritance with Apollo Federation?
I've found inheritResolversFromInterfaces: true which is an option for makeExecutableSchema. I couldn't find a way though to apply this option to a federated schema.

You can use addResolveFunctionsToSchema from graphql-tools (or addResolversToSchema from #graphql-tools/schema but I’m not sure if it works with this version) like this:
const federatedSchema = buildSubgraphSchema(typeDefs);
const schema = addResolveFunctionsToSchema({
inheritResolversFromInterfaces: true,
resolvers,
schema: federatedSchema,
});

Related

Must provide Source with graphql API call in AWS amplify

I have got an error during a graphql API call in AWS amplify
I import the queries like (just like in the documentation with *):
import * as queries from '../graphql/queries';
This is my API request where I receive the error (Must provide Source):
const data = await API.graphql(graphqlOperation(queries.nearbyZVL, {filter: filter}));
And in the same file another API request like below is working correctly:
const result = await API.graphql(graphqlOperation(queries.getProfile, { id: cognitoUserId }));
The nearbyZVL is a custom query and resolver in AWS appsync. In the appsync console the query is working fine!
Some help is appreciated! :)
Not sure why it is not generated in codegen - to create custom resolvers, did you manually edit on appsync console, or adding files under /amplify/backend? For the latter, it should codegen. If you did the former, consider do the latter.
In your case, you can simply do below:
const GetNearbyZVL = `...` // the query that works in appsync console
const data = await API.graphql(graphqlOperation(GetNearbyZVL, {filter: filter}));

best way to access req.body in policy

I am currently working on a custom plugin realizing an oauth solution. I decided to implement a proper policy that forwards the incoming login post to an external service. Therefore I have to access the body of the request (property req.body), which is only possible when the required body parser is enabled as express - middleware. Unfortunately, I could not find a comfortable way to enable body parsing within the gateway application. Consequently, I made a workaround by registering a proper route in order to access the underlying expressapp object.
pluginContext.registerGatewayRoute(app => { app.use(express.json()); }
I do not want to substitute the policy by simply registering a route, because I did not find a way to apply other policies (e.g.: CORS, RATE LIMITER...) to this route.
Please let me know if I oversee something and there is an easier way to enable body parsing.
yes, using "registerGatewayRoute" will apply middleware to every route in EG. What you can do is create a body parser policy. Policy in EG is just a wrapper around ExpressJS middleware so
so body parser policy can contain code like
{
name: 'bodyparser',
policy: (actionParams) => express.json()
}
https://www.express-gateway.io/docs/plugins/policy-development/
Now just add this policy as first one in the pipeline and it should provide req.body for all routes going through that pipeline
Thanks a lot for your helpful answer. As suggested I created a bodyParser policy. Only a small modification of the previous answer was necessary: Instead of express.json I had to call the function express.json() in order to get required middleware functionality.
const express = require('express');
module.exports = {
name: 'bodyParser',
policy: (actionParams) => express.json()
};
Works fine now and body parsing is only enabled where it is really required.

Customize path on a per-model basis, for the REST adapter

According to the URL conventions, it is possible to customize the pluralization, endpoint path and host for the REST adapter. I have a model called VoiceMenu, and the adapter is performing requests to api/voice-menus/, as per the URL-conventions. But they should instead be sent to api/voicemenus/. I do not want to change the name of my model.
How can I configure the REST adapter, for this particular model?
Assuming you have api set already on your adapter, you can set the url on a per model basis like this:
App.VoiceMenu = DS.Model.extend({
url: '/voicemenus'
...
});
Hope it helps.
I got it working with:
App.Adapter.configure('plurals', {
voice_menu : 'voicemenus',
});
I really do not like this, because this has nothing to do with plurals, but I know no other way to configure this.

Testing WebAPI actions that have authorization filters

I’ve got a Web API that I’ve added [Authorize] attributes to, which means that the unit tests I had previously now fail due to them being unauthorised. Here’s a sample of a basic test along with an initialiser method:
[TestInitialize]
public void CreateServer() {
var config = new HttpConfiguration();
WebApiConfig.Configure(config); // Create the routes
var server = new HttpServer(config);
this.client = new HttpClient(server);
}
[TestMethod]
public void MyThings_GET_Returns_All_MyThings() {
var response = this.client.GetAsync("http://localhost/api/1.0/mythings").Result;
var mythings = response.Content.ReadAsAsync<IEnumerable<MyThing>>().Result;
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
Assert.AreEqual(4, mythings.Count());
}
What I’m wondering is if there’s any way that I can either make my test log in so that it passes the authorization filter, or if there’s any way that I can pass as ASPXAUTH cookie along with the HttpClient request? Or another way of passing authorization that I haven’t thought of?
Nothing I’ve tried seems to work and I’m struggling to find any helpful info anywhere.
Thanks in advance.
What does your Authorize attribute do when it performs the authorization check? There are quite a few options that come to mind:
Have the authorize filter support multiple means of getting the "authorization token" that it requires (e.g. through an HTTP header or a querystring parameter, etc)
Right after your test initialization, clear out the filter from the configuration (so that it is not called at all). If you choose to go this route then you may wish to pop in a new filter that sets any authorization values that might be used further along the pipeline
If you are using dependency injection, move the "authorization check" into some sort of IAuthorize location that can be updated in your configuration
I would also recommend using RestSharp for making queries to your endpoints as it does a very good job of specifying headers, parameters, etc.
I decided that the way I was going about the problem was fundamentally wrong. Using cookie-based authorisation with Web API is just not a good idea, so I’ve decided to get rid of the authorize attributes and perform API-Key-based authentication instead. This makes it easier to test as I can just pass the correct API key in the request, but also means that I’m not relying on cookies for authorisation.

How do I integrate ServiceStack and DotNetNuke to provide REST services within a DNN authenticated context?

DotNetNuke 6.2 has a Services Framework that does something similar
http://www.dotnetnuke.com/Resources/Wiki/Page/DotNetNuke-6-2-Developer-Quick-Start.aspx#Services_Framework_18
The single biggest convenience of Services Framework is that authentication, authorization and establishing a DotNetNuke context are all built in.
How do I integrate ServiceStack (http://servicestack.net) with DotNetNuke to provide authentication, authorization and establish a DotNetNuke context? Any pointers?
I wrote the DNN implementation, so I can tell you about how it works. I don't know the details of ServiceStack so I can't tell you how to apply it there. When I first set out to build this, I expected it to be much more complicated than it actually is. You really only need a handful of calls into the core.
Establishing context and authentication occurs during initialization of the DnnController. One of the great things about DNN being all open source is that all these sort of details are public. Here is a link to the DnnController.cs
And here are the most interesting bits:
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext);
LoadDnnContext(requestContext.HttpContext);
AuthenticateRequest(requestContext.HttpContext, PortalSettings.PortalId);
}
protected virtual void AuthenticateRequest(HttpContextBase context, int portalId)
{
if (!context.Request.IsAuthenticated)
{
BasicAuthenticator.Instance.TryToAuthenticate(context, portalId);
}
if (!context.Request.IsAuthenticated)
{
DigestAuthenticator.Instance.TryToAuthenticate(context, portalId);
}
MembershipModule.AuthenticateRequest(context, true /*allowUnknownExtension*/);
}
protected virtual void LoadDnnContext(HttpContextBase context)
{
var domainName = TestableGlobals.Instance.GetDomainName(context.Request);
var alias = TestablePortalAliasController.Instance.GetPortalAliasInfo(domainName);
int tabId;
ValidateTabAndModuleContext(context, alias.PortalID, out tabId);
var portalSettings = new PortalSettings(tabId, alias);
context.Items["PortalSettings"] = portalSettings;
}
The Service Framework forces all routes into the form {unique portal path}/DesktopModules/{ModuleName}/API/{url} . The unique portal path is important to easily identifying the portal to which the request was sent. In most cases DNN will allow a URL of the form /Default.aspx?portalid=n, but Service Framework won't accept that, it requires that the request path match the portal alias e.g. mysite.com/childportal/... This requirement ensures that GetDomainName() will work.
I should mention that the TestableXXX classes are in the Internal namespace and therefore are not part of the official public API, and are subject to breaking changes between releases. Most of the methods on the classes have a public analog which is harder to mock but otherwise equivalent. If it is reasonable for you to make small code fixes before upgrading your servers, feel free to use the Testables. If you don't have complete control over the upgrades of your servers you should avoid the .Internal namespaces.
Service Framework supports authentication against the permission of a specific module instance. Services tied to a module must provider tab and module ids. If your services are not module specific you may omit this, and use a tabid of -1 in the PortalSettings.
ServiceFramework has it's own implementations of basic and digest auth since MVC does not provide them. I beleive that ServiceStack does provide Basic and Digest, so you probably only need to make the call to MembershipModule.AuthenticateRequest().