Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to use existing GraphQl Api without @model annotation #2685

Open
1 task done
ndeka28 opened this issue Jan 23, 2024 · 1 comment
Open
1 task done

Ability to use existing GraphQl Api without @model annotation #2685

ndeka28 opened this issue Jan 23, 2024 · 1 comment
Labels
api feature-request Request a new feature

Comments

@ndeka28
Copy link

ndeka28 commented Jan 23, 2024

Before opening, please confirm:

Language and Async Model

Kotlin - Coroutines

Amplify Categories

GraphQL API

Gradle script dependencies

    // Amplify API and Datastore dependencies
    implementation("com.amplifyframework:core:2.14.6")
    implementation("com.amplifyframework:aws-api:2.14.6")
    implementation("com.amplifyframework:core-kotlin:2.14.6")


Environment information

# Put output below this line

------------------------------------------------------------
Gradle 8.2
------------------------------------------------------------

Build time:   2023-06-30 18:02:30 UTC
Revision:     5f4a070a62a31a17438ac998c2b849f4f6892877

Kotlin:       1.8.20
Groovy:       3.0.17
Ant:          Apache Ant(TM) version 1.10.13 compiled on January 4 2023
JVM:          17.0.7 (JetBrains s.r.o. 17.0.7+0-17.0.7b1000.6-10550314)
OS:           Mac OS X 14.2.1 aarch64



</details>


### Please include any relevant guides or documentation you're referencing

https://docs.amplify.aws/android/build-a-backend/graphqlapi/set-up-graphql-api/

Describe the feature request

Currently Amplify SDK only supports generated code for @model type. e.g., Todo is a @model class, hence Amplify is generating ModelMutation or ModelQuery class (Todo implements Model)

val todo = Todo.builder()
    .name("My first todo")
    .description("todo description")
    .build()
try {
    val response = Amplify.API.mutate(ModelMutation.create(todo))
    Log.i("MyAmplifyApp", "Added Todo with id: ${response.data.id}")
} catch (error: ApiException) {
    Log.e("MyAmplifyApp", "Create failed", error)
}


//generated Todo Class
@ModelConfig(pluralName = "Todos")
public final class Todo implements Model {
......

But I have an existing endpoint, which does NOT contain @model annotation to its types. So, generated class does not contain any ModelQuery or ModelMutation class.


// Generated class does not implement Model
public final class Car23 {
..

To use Amplify.API.query, client code has to create SimpleGraphQl request using custom query and, which works, but getting complicated and lots of boilerplate code. see here

private fun getCar(id: String) : GraphQLRequest<String> {
    val document = "query GetCar23(\$id: String!) {\n" +
            "  getCar23(id: \$id) {\n" +
            "    id\n" +
            "    name\n" +
            "  }\n" +
            "}"

    return SimpleGraphQLRequest(
        document,
        mapOf("id" to id),
        String::class.java,
        GsonVariablesSerializer()
    )
}

=============================================

val response = Amplify.API.query(getCar("some_id))
val gson = Gson()
val graphqlResponse = gson.fromJson(response.data, Car::class.java)

However Aws App Sync SDK has the ability to generate all query/mutation/subscription classes, and client App does not require to create a custom query or boilerplate code. It is quite easy to use. Since it is advised to use Amplify SDK instead of Aws App Sync SDK, it would be great if Amplify SDK also has the same ability.

Initialization steps (if applicable)

No response

Code Snippet

// Put your code below this line.

//  Expecting GetCarQuery is a generated class by the Amplify SDK
val response = Amplify.API.query(GetCarQuery("some_id")

or
//  Expecting CarCreationMutation is a generated class by the Amplify SDK
val response = Amplify.API.mutate(CarCreationMutation.create(car))

amplifyconfiguration.json

{
    "UserAgent": "aws-amplify-cli/2.0",
    "Version": "1.0",
    "api": {
        "plugins": {
            "awsAPIPlugin": {
                "todo": {
                    "endpointType": "GraphQL",
                    "endpoint": "https://***********.appsync-api.eu-west-2.amazonaws.com/graphql",
                    "region": "eu-west-2",
                    "authorizationType": "API_KEY",
                    "apiKey": "da2-***********"
                }
            }
        }
    }
}

GraphQL Schema

schema {
  query: Query
  mutation: Mutation
  subscription: Subscription
}

type Car23 {
  id: String
  name: String
}

type Car23Connection {
  items: [Car23]
  nextToken: String
}

type Mutation {
  createCar23(input: CreateCar23Input!): Car23
  deleteCar23(input: DeleteCar23Input!): Car23
  updateCar23(input: UpdateCar23Input!): Car23
}

type Query {
  getCar23(id: String!): Car23
  listCar23s(filter: TableCar23FilterInput, limit: Int, nextToken: String): Car23Connection
}

type Subscription {
  onCreateCar23(id: String, name: String): Car23 @aws_subscribe(mutations : ["createCar23"])
  onDeleteCar23(id: String, name: String): Car23 @aws_subscribe(mutations : ["deleteCar23"])
  onUpdateCar23(id: String, name: String): Car23 @aws_subscribe(mutations : ["updateCar23"])
}

input CreateCar23Input {
  name: String
}

input DeleteCar23Input {
  id: String!
}

input ModelSizeInput {
  between: [Int]
  eq: Int
  ge: Int
  gt: Int
  le: Int
  lt: Int
  ne: Int
}

input TableBooleanFilterInput {
  attributeExists: Boolean
  eq: Boolean
  ne: Boolean
}

input TableCar23FilterInput {
  id: TableStringFilterInput
  name: TableStringFilterInput
}

input TableFloatFilterInput {
  attributeExists: Boolean
  between: [Float]
  eq: Float
  ge: Float
  gt: Float
  le: Float
  lt: Float
  ne: Float
}

input TableIDFilterInput {
  attributeExists: Boolean
  beginsWith: ID
  between: [ID]
  contains: ID
  eq: ID
  ge: ID
  gt: ID
  le: ID
  lt: ID
  ne: ID
  notContains: ID
  size: ModelSizeInput
}

input TableIntFilterInput {
  attributeExists: Boolean
  between: [Int]
  eq: Int
  ge: Int
  gt: Int
  le: Int
  lt: Int
  ne: Int
}

input TableStringFilterInput {
  attributeExists: Boolean
  beginsWith: String
  between: [String]
  contains: String
  eq: String
  ge: String
  gt: String
  le: String
  lt: String
  ne: String
  notContains: String
  size: ModelSizeInput
}

input UpdateCar23Input {
  id: String!
  name: String
}


Additional information and screenshots

No response

@mattcreaser mattcreaser added feature-request Request a new feature api labels Jan 23, 2024
@mattcreaser
Copy link
Contributor

Thanks for filing this feature request @ndeka28. I'll forward this internally for visibility.

For other readers, please 👍 any feature request if you agree! This helps us decide which features would be most beneficial.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api feature-request Request a new feature
Projects
None yet
Development

No branches or pull requests

2 participants