Laravel/Lighthouse, Graphql, Vue3: File Upload doesn't work - graphql

I'm trying to upload a file in my Vue3 (Vite) project using graph-QL, Apollo and Lighthouse but the documentation doesn't help me much.
I followed all instructions written in the official lighthouse upload file section adding the scalar and the mutation.
scalar Upload
#scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\Upload")
Changed the schema so that the avatar field is of Upload type
type User {
id: ID!
username: String!
email: String!
password: String!
email_verified_at: Date
active: Boolean!
user_type: UserType!
avatar: Upload ...
And set the mutation
input addSupplierInput {
active: Boolean
username: String #rules(apply: ["required", "min:5", "max:20"])
email: String #rules(apply: ["required", "email", "unique:users,email"])
password: String! #hash #rules(apply: ["required", "min:2"])
active: Boolean! #rules(apply: ["required"])
user_type: String! #rules(apply: ["required"])
avatar: Upload
Created the Upload mutation in Laravel app/GraphQL/Mutations
class Upload
public function __invoke($_, array $args)
{
$file = $args['avatar'];
return $file->storePublicly('uploads');
}
When I try to upload the file through the form I get the following error in console:
Uncaught (in promise) Error: Variable "$avatar" got invalid value "C:\fakepath\Schermata 2022-10-20 alle 12.37.53.png"; Expected type Upload; Could not get uploaded file, be sure to conform to GraphQL multipart request specification: https://github.com/jaydenseric/graphql-multipart-request-spec Instead got: C:\fakepath\Schermata 2022-10-20 alle 12.37.53.png
As far I understand I've to do something of a client side multipart file specification but I don't find any solution for Vue.js (or I don't understand what to do).
Please, any help will be appreciated. I'm simply getting crazy and I don't find any paper/video in internet that can help me .

I finally found the solution.
I've followed this article here, installed the apollo-upload-client package, updated the main.js file removing the createHttpLink and saved the file.
main.js BEFORE
import {
ApolloClient,
createHttpLink,
InMemoryCache,
} from '#apollo/client/core';
// HTTP connection to the API
const httpLink = createHttpLink({
uri: 'http://localhost/graphql',
});
// Cache implementation
const cache = new InMemoryCache();
// Create the apollo client
const apolloClient = new ApolloClient({
link: httpLink,
cache,
});
main.js AFTER
import { ApolloClient, InMemoryCache } from '#apollo/client/core';
import { createUploadLink } from 'apollo-upload-client';
// Cache implementation
const cache = new InMemoryCache();
// Create the apollo client
const apolloClient = new ApolloClient({
link: createUploadLink({
uri: 'http://localhost/graphql',
}),
cache,
});
I just wonder why this solution doesn't appear on the official documentation.

Related

Set Cookies in apollo server azure functions

I am using apollo server in the azure function. I want to set cookies from apollo server azure functions. But it's not working. It doesn't throw any kind of errors.
How do I set cookies in apollo server azure functions? I tried this way but it's not working.
Here is my code
import { ApolloServer, gql } from "apollo-server-azure-functions";
import { ApolloServerPluginLandingPageLocalDefault } from "apollo-server-core";
import { serialize, parse } from "cookie";
// Construct a schema, using GraphQL schema language
const typeDefs = gql`
type Query {
user: User
}
type User {
id: ID!
name: String!
email: String!
}
`;
// Provide resolver functions for your schema fields
const resolvers = {
Query: {
user: (parents, args, { request, context }, info) => {
const cookie = serialize("token", "123", {
expires: new Date(Date.now() + 900000),
httpOnly: true,
});
context.res.setHeader("Set-Cookie", cookie);
return {
id: "1",
name: "John Doe",
email: "john#example.com",
};
},
},
};
// #ts-ignore
const server = new ApolloServer({
typeDefs,
resolvers,
debug: true,
plugins: [ApolloServerPluginLandingPageLocalDefault({ embed: true })],
context: (context) => {
return context;
},
});
export default server.createHandler({
cors: {
origin: ["*", "https://studio.apollographql.com"],
methods: ["GET", "POST", "OPTIONS"],
allowedHeaders: [
"access-control-allow-header",
"access-control-allow-credentials",
"access-control-allow-origin",
"content-type",
],
},
});
There is no documentation available for apollo server azure functions.
Official repository from apollo server azure functions: https://github.com/Azure-Samples/js-e2e-azure-function-graphql-hello.git
Sharing the discussion with the team internal and posting the update as updated here.
After looking at the issue, the infrastructure, and the announcement from Apollo for this package, I believe Apollo is the correct organization to post this issue because Apollo is providing the server in this sample. It just happens to be running on an Azure Function. Additionally, when I look for a solution on Apollo, it looks like the ApolloServer dependency needs to be swapped out for an Apollo server for express dependency in order to successfully set the cookie.
None of this is great news. I apologize for this.
I believe the sample works in this repo without cookes and doesn't currently include cookies in the code. Moving forward with the Apollo dependency, we will re-evaluate its use based on this feedback.

Amplify/React AppSync graphql subscriptions #auth error

Hello there :slight_smile:
I've a little problem related with the #auth.
(Amplify + React + AppSync)
schema.graphql
type Ticket #model
#auth(rules: [
{allow: owner, provider: userPools},
])
{
id: ID!
status: String!
owner: String!
description: String!
}
build -> schema.graphql
type Subscription {
onCreateTicket(owner: String!): Ticket #aws_subscribe(mutations: ["createTicket"])
onUpdateTicket(owner: String!): Ticket #aws_subscribe(mutations: ["updateTicket"])
onDeleteTicket(owner: String!): Ticket #aws_subscribe(mutations: ["deleteTicket"])
}
All operations (create update etc.) are working fine:
const {data: {listTickets: {items: items, nextToken}}} = await API
.graphql(graphqlOperation(listTickets, {
owner: user.username
})) as GraphQLResult;
except with subscriptions:
const subClient = API
.graphql(graphqlOperation(onUpdateTicket, {
owner: user.username
})) as Observable<object>;
subscription = subClient.subscribe({
next: (data: any) => console.log('subscription data:', data),
error: error => console.warn('subscription error: ', error)
});
The subscription never trigger.
(No errors, no warnings)
Any help would be much appreciated!
Thanks
It was working!!!
I forgot to check "owner" not only in the input* but also in the fields below.
#aws-amplify-devs Could you please add this info to the documentation? :)
Could save many hours.

Nested GraphQL mutations with AWS Amplify

I'm struggling to write a nested GraphQL mutation for a React Native app I'm building with GraphQL client being AWS Amplify API. Here's my type definition file
type Game #model {
id: ID!
gameId: String!
players: [Player!]!
}
type Player #model {
id: ID!
username: String!
}
Here's my attempt to create a mutation to create a new Game
import API, { graphqlOperation } from '#aws-amplify/api';
const CreateGame = `
mutation ($gameId: String! $username: String!) {
createGame(input: {
gameId: $gameId,
players: [{ username: $username }]
}) {
id
gameId
players
}
}
`;
const gameObj = {
gameId: 'example_game_id',
username: 'example_username'
};
const queryResp = await API.graphql(graphqlOperation(CreateGame, gameObj));
console.log(queryResp.data);
Here's the error I get
"Validation error of type WrongType: argument 'input' with value 'ObjectValue{objectFields=[ObjectField{name='gameId', value=VariableReference{name='gameId'}}, ObjectField{name='players', value=ArrayValue{values=[ObjectValue{objectFields=[ObjectField{name='username', value=VariableReference{name='username'}}]}]}}]}' contains a field not in 'CreateGameInput': 'players' # 'createGame'"

GraphQL Query returning null. Not sure why though [duplicate]

This question already has answers here:
Why does a GraphQL query return null?
(6 answers)
Closed 2 years ago.
I'm having some trouble with a graphQL query returning null and i'm not quite sure why its returning null. I've read several posts similar to this post but none of those posts have helped identify my exact problem.
I think it has something to do with how i'm passing/getting parameters, since my query with no parameters works fine, but i'm not sure since I can't find any other examples online.
Any help would be greatly appreciated.
I'm using apollo-server, graphql, and a community SQL datasource implementation which uses Knex to create a database connection.
There are two queries I can make.
allParts() - this query works as expected and returns all parts in my database with requested graphQL fields
getPart(itemnum) - this is the query that is not currently working.
graphQL Query:
query{
getPart(itemnum: "T|0000000000001"){
desc
}
}
graphQL response:
"message": "Cannot return null for non-nullable field Part.desc.",
SQL query that is being executed based on Knex debug message:
method: 'select',
options: {},
timeout: false,
cancelOnTimeout: false,
bindings: [ 'T|0000000000001' ],
__knexQueryUid: '3a8234eb-0a5c-46db-ad8e-5508288c9a86',
sql: 'select * from `part` where `itemnum` = ?'
index.js:
const { ApolloServer } = require('apollo-server');
const typeDefs = require('./schema');
const resolvers = require ('./resolvers')
const PartAPI = require ('./datasources/partAPI');
const knexConfig = {
client: "sqlite3",
connection: {
/* CONNECTION INFO */
filename: "./TEAM_material.db3"
},
debug: true
};
const server = new ApolloServer({
typeDefs,
resolvers,
dataSources: () => ({
partAPI: new PartAPI(knexConfig),
}),
introspection: true,
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
partAPI.js:
const { SQLDataSource } = require("datasource-sql");
const MINUTE = 60;
class PartAPI extends SQLDataSource {
getPart(itemnum){
return this.knex.select('*').from('part').where({itemnum});
}
getAllParts(){
const query = this.knex.select('*').from('part').cache(MINUTE);
console.log (query);
return query;
}
}
module.exports = PartAPI;
schema.js
// src/schema.js
const { gql } = require('apollo-server')
const typeDefs = gql`
#Types
type Part {
itemnum: String!
desc: String!
vendor: String!
manuf: String!
venlist: Float!
price: Float!
teamlist: Float!
teamsell: Float!
unitypart: String!
pkgqty: Int!
ioType: String!
preferred: Boolean!
filterlvl1: String!
filterlvl2: String!
filterlvl3: String!
filterlvl4: String!
ipwiretype: String!
opwiretype: String!
obsolete: Boolean!
}
#Queries
type Query {
getPart(itemnum: String!): Part
allParts: [Part!]!
}
`;
module.exports = typeDefs
resolvers.js
// src/resolvers.js
const resolvers = {
Query: {
getPart: (_,args,{dataSources}) => dataSources.partAPI.getPart(args.itemnum),
allParts: (_,__,{dataSources}) => dataSources.partAPI.getAllParts(),
},
};
module.exports = resolvers
turns out my schema was incorrect. The getPart query was expecting a Part but instead my query was returning an array of Part.
old Schema
#Queries
type Query {
getPart(itemnum: String!): Part
allParts: [Part!]!
}
`;
new Schema
#Queries
type Query {
getPart(itemnum: String!): [Part]!
allParts: [Part!]!
}
`;

GraphQLError: Syntax Error: Cannot parse the unexpected character "."

I am currently using Apollo-server as my GraphQL server of choice and anytime I try to run tests I get the error indicated in the title. However, my server implementation works as expected.
import 'cross-fetch/polyfill';
import ApolloClient, { gql } from 'apollo-boost';
const client = new ApolloClient({
uri: 'http://localhost:4000/',
});
const USER = {
invalidPassWord : {
name: 'Gbolahan Olagunju',
password: 'dafe',
email: 'gbols#example.com'
},
validCredentials: {
name: 'Gbolahan Olagunju',
password: 'dafeMania',
email: 'gbols#example.com'
},
usedEmail: {
name: 'Gbolahan Olagunju',
password: 'dafeMania',
email: 'gbols#example.com'
}
};
describe('Tests the createUser Mutation', () => {
test('should not signup a user with a password less than 8 characters', () => {
const createUser = gql`
mutation {
createUser(data: USER.invalidPassWord){
token
user {
name
password
email
id
}
}
}
`
client.mutate({
mutation: createUser
}).then(res => console.log(res));
})
})
There is a problem with the document used in your test. USER.invalidPassWord is not valid GraphQL syntax. Presumably you meant to use a template literal there to reference the USER variable defined earlier.
Doing the GrapQL tutorial at
https://www.howtographql.com/react-apollo/1-getting-started/
gives the same error.
I have razed the "same" issue at their site, though is the problem another in my case.
https://github.com/howtographql/howtographql/issues/1047

Resources