I'm trying to follow along this article on how to create a mutation on a rails server using GraphQl https://www.howtographql.com/graphql-ruby/4-authentication
However, I'm stuck at the CreateUser Mutation step, I get the follow error hash when trying it out in GraphiQL:
{
"errors": [
{
"message": "Field 'createUser' is missing required arguments: input",
"locations": [
{
"line": 45,
"column": 3
}
],
"path": [
"mutation CreateUser",
"createUser"
],
"extensions": {
"code": "missingRequiredArguments",
"className": "Field",
"name": "createUser",
"arguments": "input"
}
},
{
"message": "Field 'createUser' doesn't accept argument 'username'",
"locations": [
{
"line": 46,
"column": 5
}
],
"path": [
"mutation CreateUser",
"createUser",
"username"
],
"extensions": {
"code": "argumentNotAccepted",
"name": "createUser",
"typeName": "Field",
"argumentName": "username"
}
},
{
"message": "Field 'createUser' doesn't accept argument 'authProvider'",
"locations": [
{
"line": 47,
"column": 5
}
],
"path": [
"mutation CreateUser",
"createUser",
"authProvider"
],
"extensions": {
"code": "argumentNotAccepted",
"name": "createUser",
"typeName": "Field",
"argumentName": "authProvider"
}
},
{
"message": "Variable $username is declared by CreateUser but not used",
"locations": [
{
"line": 44,
"column": 1
}
],
"path": [
"mutation CreateUser"
],
"extensions": {
"code": "variableNotUsed",
"variableName": "username"
}
},
{
"message": "Variable $email is declared by CreateUser but not used",
"locations": [
{
"line": 44,
"column": 1
}
],
"path": [
"mutation CreateUser"
],
"extensions": {
"code": "variableNotUsed",
"variableName": "email"
}
},
{
"message": "Variable $password is declared by CreateUser but not used",
"locations": [
{
"line": 44,
"column": 1
}
],
"path": [
"mutation CreateUser"
],
"extensions": {
"code": "variableNotUsed",
"variableName": "password"
}
}
]
}
I just followed the code in the article, my files:
create_user.rb
module Mutations
class CreateUser < BaseMutation
# often we will need input types for specific mutation
# in those cases we can define those input types in the mutation class itself
class AuthProviderSignupData < Types::BaseInputObject
argument :credentials, Types::AuthProviderCredentialsInput, required: false
end
argument :username, String, required: true
argument :auth_provider, AuthProviderSignupData, required: false
type Types::UserType
def resolve(username: nil, auth_provider: nil)
User.create!(
username: username,
email: auth_provider&.[](:credentials)&.[](:email),
password: auth_provider&.[](:credentials)&.[](:password)
)
end
end
end
user_type.rb
module Types
class UserType < BaseObject
field :id, ID, null: false
field :email, String, null: false
field :username, String, null: false
field :photo, String, null: true
field :phone, String, null: false
field :island, IslandType, null: false, method: :island
field :archipel, ArchipelType, null: false, method: :archipel
field :created_at, String, null: false
field :updated_at, String, null: false
end
end
I have no clue where this 'input' thing is coming from.
Without realizing I inilialized my project with a configuration that used Relay.
By commenting this code inside my **_schema.rb file it worked again.
# Opt in to the new runtime (default in future graphql-ruby versions)
# use GraphQL::Execution::Interpreter
# use GraphQL::Analysis::AST
# Add built-in connections for pagination
# use GraphQL::Pagination::Connections
As well as these lines inside base_mutation.rb and replaces with these.
# class BaseMutation < GraphQL::Schema::RelayClassicMutation
# argument_class Types::BaseArgument
# field_class Types::BaseField
# input_object_class Types::BaseInputObject
# object_class Types::BaseObject
# end
class BaseMutation < GraphQL::Schema::Mutation
null false
end
If you're not interested in commenting out fields... I ran across the same error. For whatever reason input is the name of the key you pass your arguments into as a hash/object.
Example from using this tutorial:https://www.howtographql.com/graphql-ruby/3-mutations/
mutation {
createLink(input: {
url: "foo",
description:"bar"
}) {
url
description
}
}
Related
app/models/author.rb:
class Author < ApplicationRecord
validates :name, presence: true,
uniqueness: { case_sensitive: false }
end
app/serializers/author_serializer.rb:
class AuthorSerializer < ActiveModel::Serializer
attributes :id, :name, :bio
end
spec/spec_helper.rb:
#...
require 'json_matchers/rspec'
JsonMatchers.schema_root = 'spec/support/api/schemas.author.json':
#...
spec/support/api/schemas/authors/show.json:
{
"id": "file:/authors/show.json#",
"type": "object",
"definitions": {
"authors": {
"description": "A collection of authors",
"example": [{ "id": "1", "name": "Name" }],
"type": "array",
"items": {
"$ref": "file:/author.json#"
}
}
},
"required": ["authors"],
"properties": {
"authors": {
"$ref": "#/definitions/authors"
}
}
}
spec/requests/authors_show_request_pec.rb:
RSpec.describe 'Authors', type: :request do
setup { host! 'api.example.com' }
describe 'GET /author/:id' do
let!(:author) { create(:author, id: 13, name: 'Name', bio: 'bio') }
it 'returns requested author' do
get author_path(13)
expect(response).to have_http_status(200)
author_from_response = JSON.parse(response.body)
expect(author_from_response['name']).to eq(author.name)
expect(author_from_response['bio']).to eq(author.bio)
expect(response).to match_json_schema('author')
end
end
end
Response body contains all expected data, but spec if falinig to validate matching response to json schema.
Json_matchers gem seems to be configured according to manual.
Error that appears:
JsonMatchers::InvalidSchemaError:
783: unexpected token at '}
'
Try removing the trailing commas. The ruby JSON parser does not like them.
Your JSON response should be:
{
"id": "file:/authors/index.json#",
"type": "object",
"definitions": {
"authors": {
"description": "A collection of authors",
"example": [{ "id": "1", "name": "Name" }],
"type": "array",
"items": {
"$ref": "file:/author.json#"
}
}
},
"required": ["authors"],
"properties": {
"authors": {
"$ref": "#/definitions/authors"
}
}
}
Notice no trailing commas after the "items", "authors" nor "properties".
I'm using swagger for quite a bit now, we have started documenting our code using it, in one place there's an API response which returns multiple objects in the included block.
Example:
{
"data": {
"id": "1",
"type": "schoolPositions",
"attributes": {
"description": "teases the students",
"mustHaves": "principle"
},
"relationships": {
"schoolLocation": {
"data": {
"id": "72",
"type": "schoolLocations"
}
},
"schoolCompensation": {
"data": {
"id": "75",
"type": "schoolCompensations"
}
},
"jobSpecs": {
"data": [
{
"id": "82",
"type": "schoolAttachments"
}
]
}
}
},
"included": [
{
"id": "72",
"type": "schoolLocations",
"attributes": {
"city": "Berhampore",
"state": "West Bengal",
"postalCode": "742101",
"country": "India",
"globalRegionId": 30,
"regionId": 683
}
},
{
"id": "75",
"type": "schoolCompensations",
"attributes": {
"salary": "",
"bonus": "",
"equity": "",
"currencyId": null,
"equityType": "percent",
"salaryDescription": null
}
},
{
"id": "82",
"type": "schoolAttachments",
"attributes": {
"attachmentType": "JobSpecificationAttachmentType",
"fileFileName": "vs.jpg",
"fileContentType": "image/jpeg",
"fileFileSize": 2410039,
"fileUpdatedAt": "2018-12-12T07:06:38Z",
"downloadUrl": "001-vs.jpg?1544598398",
"klass": "SchoolAttachments"
}
}
]
I have wasted an entire day on the internet and documentation trying to document the included part, but I'm going wrong somewhere
response 200 do
key :description, 'School Data'
schema do
property :data do
key :type, :array
items do
key :'$ref', :School
end
end
property :included do
key :type, :array
items do
key :'$ref', :SchoolLocations
key :'$ref', :SchoolCompensations
key :'$ref', :SchoolAttachments
end
end
end
end
This shows only the SchoolAttachments in the included part.
I have tried using allOff but it doesn't work.
I hope this is a legit question, I searched everywhere for an example or any source of information on how to do this. I tried this https://github.com/fotinakis/swagger-blocks/issues/17 as well. But the same result.
The end result I would like to get generated is below:
{
"name": "Awesome Promotion",
"description": "30% off",
"qualifiers": [
{
"id": 12,
"type": "Rental"
},
{
"id": 13,
"type": "Qualifier",
"user_id": 23
},
{
"id": 14,
"type": "First",
"location_id": 32
}
]
I have the model writen out like this:
swagger_schema :PromotionResponse do
property :name, type: :string, example: 'Awesome Promotion'
property :description, type: :string, example: '30% off'
property :qualifiers do
key :type, :array
items do
property :id, type: :integer, example: 2
property :type, type: :string, exmple: 'Location'
end
end
end
What gets generated by swagger right now:
{
"name": "Awesome Promotion",
"description": "30% off",
"qualifiers": [
{
"id": 2,
"type": "Location"
}
]
}
What is the proper way to define different object structures inside an array schema?
I'm trying to write an API endpoint for creating Redemptions in my app.
In Rails, my model is such that Redemption has many Items (class_name: RedemptionItems).
Here's my POST Body, following what I assume is the correct JSONAPI Specification (since there is no explicit spec for creating parent and child records in one request).
{
"data": {
"type": "redemptions",
"relationships": {
"items": {
"data": [{
"type": "items",
"attributes": { "offer_id": "1", "quantity": "2" }
},
{
"type": "items",
"attributes": { "offer_id": "1", "quantity": "3" }
},
{
"type": "items",
"attributes": { "offer_id": "123", "quantity": "3" }
}
]
}
}
}
}
I'm using JSONAPI::Resources. I have defined my JSONAPI::Resources thus:
class Platform::Api::Members::RedemptionItemResource < JSONAPI::Resource
model_name 'Platform::RedemptionItem'
has_one :redemption
end
class Platform::Api::Members::RedemptionResource < JSONAPI::Resource
model_name 'Platform::Redemption'
has_many :items, class_name: 'RedemptionItem'
end
It's currently giving me an inavlid links object error, which doesnt tell me anything on how I must improve my request body.
{
"errors": [
{
"title": "Invalid Links Object",
"detail": "Data is not a valid Links Object.",
"code": "115",
"status": "400"
}
]
}
I try to change some field when I create/update data whith loopback. The POST method works, but now the PUT method is down.
my category.json:
{
"name": "category",
"base": "PersistedModel",
"properties": {
"name": {
"type": "string",
"required": true
},
"image": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": []
}
and the category.js for define methods:
module.exports = function(categorie) {
categorie.observe('before save', function(ctx, next){
ctx.instance.name = ctx.instance.name.toUpperCase().trim();
ctx.instance.image = ctx.instance.image.trim();
ctx.instance.image = ctx.instance.image.charAt(0).toUpperCase() + ctx.instance.image.slice(1);
next();
});
};
I receive this error message:
{
"error": {
"name": "TypeError",
"status": 500,
"message": "Cannot read property 'name' of undefined",
"stack": "TypeError: Cannot read property 'name' of undefined\n at /home/pitt/warm-wildwood-2324/common/models/category.js:5:35\n at notifySingleObserver (/home/pitt/warm-wildwood-2324/node_modules/loopback-datasource-juggler/lib/model.js:600:22)\n (...) at Function.ModelBaseClass.notifyObserversOf (/home/pitt/warm-wildwood-2324/node_modules/loopback-datasource-juggler/lib/model.js:593:8)"
}
}
ctx.instance is not undefined while partial update of possibly multiple models, instead access ctx.data property.
check the docs