Calling .Net Odata API from GraphQL API Query and Mutation - graphql

my requirement is to call Odata .net API from GraphQL service.
My GQL query
query
{
cARequests {
id
cARequestStatus
reviewedBy {
name
email
}
assignedTo {
name
email
}
reviewedBy {
name
}
requestDate
reasonIfRejected
mPxN
mPxN
account {
accountNumber
}
}
}
My ODATA Request
[HttpGet(Name = "GetCARequest")]
[EnableQuery(PageSize=10)]
public IQueryable<GQLOdata> Get()
{
return Enumerable.Range(1, 5).Select(index => new GQLOdata
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.AsQueryable();
}
I dont know how to call this ODATA API from GraphQL API. What configuration I have to make and what services I have to add. Please guide me in the right direction

Related

Is there any way to create custom aws lambda authorizer using Spring Boot Function?

I am trying to create a custom API Gateway lambda authorizer using Spring Cloud Function.
But when I am trying to return policy document as Map<String,Object> from Spring Function, Spring returning it as body along with some extra metadata. So ApiGateway treating it as invalid json. How to return only policy document.
This is what the String Function returning when I return Map<String,Object>. My Map Object data is in body.
{
"isBase64Encoded":false,
"headers":{
"id":"6b9da9d5-23a7-b555-aecf-90e6134779b8",
"contentType":"application/json",
"timestamp":"1630300611676"
},
"body":"{\"policyDocument\":{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"execute-api:Invoke\",\"Resource\":\"arn-value\",\"Effect\":\"Allow\"}]},\"context\":{\"name\":\"test\"},\"principalId\":\"813bf219-6039-4065-bcce-3e03b6996872\"}",
"statusCode":200
}
But it should actually return only body part for ApiGateway to work correctly.
{
"policyDocument":{
"Version":"2012-10-17",
"Statement":[
{
"Action":"execute-api:Invoke",
"Resource":"arn-value",
"Effect":"Allow"
}
]
},
"context":{
"name":"test"
},
"principalId":"813bf219-6039-4065-bcce-3e03b6996872"
}
My Spring Cloud Function code is below. It is only test function without proper logic.
#Bean
public Function<APIGatewayProxyRequestEvent, Map<String,Object>> authorise() {
return request -> {
String token = request.getHeaders().get("Authorization");
String arn = String.format("arn:aws:execute-api:%s:%s:%s/%s/%s/",
System.getenv("AWS_REGION"),
request.getRequestContext().getAccountId(),
request.getRequestContext().getApiId(),
request.getRequestContext().getStage(),
request.getRequestContext().getHttpMethod());
// Policy policy = jwtToken.getPolicy(token, arn);
try{
String allow = request.getHttpMethod().equalsIgnoreCase("GET")?"Allow":"Deny";
JSONObject json = new JSONObject();
json.put("principalId", UUID.randomUUID().toString())
.put("policyDocument",
new JSONObject()
.put("Version", "2012-10-17")
.put("Statement",
new JSONArray()
.put(new JSONObject()
.put("Action", "execute-api:Invoke")
.put("Effect", allow)
.put("Resource", arn)
)
)
)
.put("context", new JSONObject().put("name", "test"));
return json.toMap();
}catch(Exception e){
logger.error("",e);
}
return null;
};
}

GraphQL Filter on Enum Column

Below is my GraphQL Query to Fetch Posts from Strapi backend.
Please note I am running this on my Nuxt app.
Now I want to bring only those posts which have post_status = "Publish"
post_status is a ENUM field with two option as Draft and Publish
query GetPosts{
posts {
id
post_title
post_excerpt
post_featured_image{url}
post_content
post_category{category_name}
postingredients{ingredient{ingredient_name}, ingredient_unit}
updated_at
post_author{username}
post_slug
}
}
I did not understand how can I get
How to bring post_status values on my original Query
How to filter on the post_status where I can get only Published posts.
query GetStatusEnum{
__type(name: "ENUM_POST_POST_STATUS") {
name
enumValues {
name
} } }
Result of the above:
{
"data": {
"__type": {
"name": "ENUM_POST_POST_STATUS",
"enumValues": [
{
"name": "Publish"
},
{
"name": "Draft"
}
]
}
}
}
To add your post_status in your original request you just have to add it in the list of the attributes you want to fetch.
{
posts {
id
post_title
post_status <- here /!\
}
}
Here is the query to fetch Posts that have Publish as post_status
{
posts(where: { post_status: "Publish" }) {
id
post_title,
post_status
}
}
You can play with GraphQL playground in your strapi application:
http://localhost:1337/graphql
You will see in the right of you page a docs button that will show you all the information you need to create your GraphQL request.
I had a similar scenario (though I'm using a Prisma layer as well so keep that in mind) and i'm not sure that you can filter for enum values on the call but you can filter what it returns.
const posts = [the array of all posts]
const isPublished = (post) => {
if (post.post_status.includes('Publish')) {
return post;
}
}
let publishedPosts = posts.filter(isPublished);
return publishedPosts;

Update Local State when Creating and Deleting Associations in Apollo Client

I have objects of type student and team in my schema and a table student_team that keeps records of their relationships.
To manage these I use the following calls:
// to add a student team relationship
mutation CreateStudentTeam($studentId: UUID!, $teamId: UUID!) {
createStudentTeam(
input: { studentTeam: { studentId: $studentId, teamId: $teamId } }
) {
student {
id
}
team {
id
}
}
}
// to remove a student team relationship
mutation DeleteStudentTeam($studentId: UUID!, $teamId: UUID!) {
deleteStudentTeamByStudentIdAndTeamId(input: {studentId:$studentId, teamId:$teamId}) {
student {
id
}
team {
id
}
}
}
// to view teams with students
query Teams {
teams {
nodes {
id
name
students {
nodes {
id
fullName
}
}
}
}
}
My application presents data based on these relationships as listings.
A team might be presented with a listing of students.
I'm a bit confused about how to update the local state after making these calls.
Would the best thing to do to just redo the fetch for the data with the Teams query?
I'd love to know how best to do it with the Apollo Link State.
Thanks!
You need to do it manually using update prop passed:
graphql(YourMutation, {
options: {
update: (cache, result) => {
const query = TeamsQuery
const currentQueryData = cache.readQuery({query})
const updatedData = //change your data regarding of the mutation
cache.writeQuery({query, data: graphql updatedData })
}
}
}
also have a look at this part of the docs

How to get variant by variant Id from product object using by graphql Shopify

Query so far
{
product1: product(id: "gid://shopify/Product/777854222396") {
title
totalVariants
variants(first:99) {
.....
}
hasOutOfStockVariants
}
product2: product(id: "gid://shopify/Product/511571296316") {
title
}
}
What can be done to fetch variant based on id
I have found ProductVariant on their GraphQL Admin API reference docs, you can take reference from their else I didn't find any ProductVariant Schema open at QueryRoot as defined here in the open graphQL admin panel although they have mentioned an example.
query {
productVariant(id: "gid://shopify/ProductVariant/10782354800682") {
inventoryItem {
inventoryLevels (first:10) {
edges {
node {
location {
name
}
available
}
}
}
}
}
}

Cannot get Relay to make GraphQL Call over the network

I am new to Relay, and I am having problems making it work with a GraphQL server.
I have adapted the Tea sample from the relay homepage to the SWAPI relay service. I cloned swapi-graphql, and added cors to the express server. I tested the link with this code:
var query = `
{
allFilms {
edges {
node {
id
}
}
}
}
`
fetch("http://localhost:50515/graphiql?query=" + query)
.then(response=>response.json())
.then(json=>console.log(json))
I got a response from the server, I saw some network action, it worked! I can communicate with the graphiql service.
Next, I created a query that was structured similar to the TeaStoreQuery. I tested it, and it returned the expected results.
query AllFilmQuery {
allFilms {
...filmListFragment
}
}
fragment filmListFragment on FilmsConnection {
edges {
node {
...filmFragment
}
}
}
fragment filmFragment on Film {
id
title
releaseDate
}
HOW DO YOU MAKE THIS WORK WITH RELAY??
I cannot figure out how to use Relay to query the server. Here is the code that I adapted from the Tea sample.
import { render } from 'react-dom'
import {
RootContainer,
createContainer,
Route,
injectNetworkLayer
} from 'react-relay'
// React component for each star wars film
const Film = ({ id, title, releaseDate }) =>
<li key={id}>
{title} (<em>{releaseDate}</em>)
</li>
// Relay container for each film
const FilmContainer = createContainer(Film, {
fragments: {
film: () => Relay.QL`
fragment on Film {
id,
title,
releaseDate
}
`
}
})
// React component for listing films
const FilmList = ({ films=[] }) =>
<ul>
{films.map(
film => <Film {...film} />
)}
</ul>
// Relay container for Listing all Films
const FilmListContainer = createContainer(FilmList, {
fragments: {
films: () => Relay.QL`
fragment on FilmsConnection {
edges {
node {
${ Film.getFragment('film') }
}
}
}
`
}
})
// The Home Route
class FilmHomeRoute extends Route {
static routeName = 'Home'
static queries = {
allFilms: (Component) => Relay.QL`
query AllFilmQuery {
allFilms {
${Component.getFragment('allFilms')}
}
}
`
}
}
// Is this how you setup a network layer
// I am using CORS, and I testing the graphql service with fetch
// The graphql service works but Relay never seems to try to connect
Relay.injectNetworkLayer(
new Relay.DefaultNetworkLayer('http://localhost:50515/graphiql')
)
render(
<RootContainer
Component={FilmListContainer}
route={new FilmHomeRoute()}
/>,
document.getElementById('react-container')
)
When I run this sample (source | output) I do not see any attempts at making network requests. I do see an error "Cannot render map of null". It seems like it cannot map the allfilms data.
What am I doing wrong?
According to section 5.1 of this document, the "Relay Object Identification Specification":
Relay‐compliant servers may expose root fields that are not plural identifying root fields; the Relay client will just be unable to use those fields as root fields in its queries.
Based on this specification, Relay can not query plural fields at the root of a query unless the field takes a list of arguments that exactly maps to the results. That means the allFilms field cannot be used with Relay. You can read more about the limitations in this other StackOverflow answer: How to get RelayJS to understand that a response from GraphQL is an array of items, not just a single item
If you would like to have a GraphQL schema with root fields that return arrays, you might want to use a different GraphQL client, since Relay is particularly restrictive in what kinds of schemas it works with. graphql.org has a list: http://graphql.org/code/#graphql-clients

Resources