Мутация для создания отношений в AWS AppSync

Я без особого успеха пытался запустить мутацию, чтобы создать отношения между двумя отдельными типами.

** СХЕМА **

(Я использовал «Создать ресурсы» для создания таблиц в DynamoDB)

type Comment {
    eventId: ID!
    commentId: String!
    content: String
}

type CommentConnection {
    items: [Comment]
    nextToken: String
}

input CreateCommentInput {
    eventId: ID!
    commentId: String!
    content: String
}

input CreateEventInput {
    id: ID!
    name: String
    where: String
    when: String
    description: String
}

input DeleteCommentInput {
    eventId: ID!
}

input DeleteEventInput {
    id: ID!
}

type Event {
    id: ID!
    name: String
    where: String
    when: String
    description: String
    comments(limit: Int, nextToken: String): CommentConnection
}

type EventConnection {
    items: [Event]
    nextToken: String
}

type Mutation {
    createEvent(input: CreateEventInput!): Event
    updateEvent(input: UpdateEventInput!): Event
    deleteEvent(input: DeleteEventInput!): Event
    createComment(input: CreateCommentInput!): Comment
    updateComment(input: UpdateCommentInput!): Comment
    deleteComment(input: DeleteCommentInput!): Comment
    commentOnEvent(input: commentOnEventInput!): Comment
}

type Query {
    fetchEvent(id: ID!): Event
    getEvent(id: ID!): Event
    listEvents(first: Int, after: String): EventConnection
    getComment(eventId: ID!): Comment
    listComments(first: Int, after: String): CommentConnection
}

type Subscription {
    onCreateEvent(
        id: ID,
        name: String,
        where: String,
        when: String,
        description: String
    ): Event
        @aws_subscribe(mutations: ["createEvent"])
    onUpdateEvent(
        id: ID,
        name: String,
        where: String,
        when: String,
        description: String
    ): Event
        @aws_subscribe(mutations: ["updateEvent"])
    onDeleteEvent(
        id: ID,
        name: String,
        where: String,
        when: String,
        description: String
    ): Event
        @aws_subscribe(mutations: ["deleteEvent"])
    onCreateComment(eventId: ID, commentId: String, content: String): Comment
        @aws_subscribe(mutations: ["createComment"])
    onUpdateComment(eventId: ID, commentId: String, content: String): Comment
        @aws_subscribe(mutations: ["updateComment"])
    onDeleteComment(eventId: ID, commentId: String, content: String): Comment
        @aws_subscribe(mutations: ["deleteComment"])
}

input UpdateCommentInput {
    eventId: ID!
    commentId: String
    content: String
}

input UpdateEventInput {
    id: ID!
    name: String
    where: String
    when: String
    description: String
}

input commentOnEventInput {
    eventId: ID!
    content: String
}

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

** МУТАЦИИ **

мутация №1:

mutation {
    createEvent(input: {
    id: "id8888"
        name: "some event"
    where: "Tokyo"
        when: "tomorrow"
        description: "desc for event"
  })
  {
    id
        name
    }
}

мутация №1 дает:

{
  "data": {
    "createEvent": {
      "id": "id8888",
      "name": "some event"
    }
  }
}

мутация №2:

mutation {
  commentOnEvent(input : {
    eventId: "id8888"
    commentId: "id2222"
    content: "some content"
  })
  {
    commentId
    content
  }
}

мутация # 2 дает:

{
  "data": {
    "commentOnEvent": null
  }
}

В образце React, созданном AWS AppSync, автоматически создается commentId, но я не могу воссоздать его в созданной вручную схеме и ресурсе.

Я хотел бы знать, как я могу установить отношения между отдельными типами и запросить их. Кто-нибудь успешно это сделал ??

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
3 456
1

Ответы 1

Начав с функции консоли «Создание ресурсов», мы поговорим о том, как это работает. Предположим, у нас есть эта схема.

type Comment {
    eventId: ID!
    commentId: String!
    content: String
}

type CommentConnection {
    items: [Comment]
    nextToken: String
}

input CreateCommentInput {
    eventId: ID!
    commentId: String!
    content: String
}

input CreateEventInput {
    id: ID!
    name: String
    where: String
    when: String
    description: String
}

input DeleteCommentInput {
    eventId: ID!
}

input DeleteEventInput {
    id: ID!
}

type Event {
    id: ID!
    name: String
    where: String
    when: String
    description: String
    comments(limit: Int, nextToken: String): CommentConnection
}

type EventConnection {
    items: [Event]
    nextToken: String
}

type Mutation {
    createEvent(input: CreateEventInput!): Event
    updateEvent(input: UpdateEventInput!): Event
    deleteEvent(input: DeleteEventInput!): Event
    createComment(input: CreateCommentInput!): Comment
    updateComment(input: UpdateCommentInput!): Comment
    deleteComment(input: DeleteCommentInput!): Comment
}

type Query {
    getEvent(id: ID!): Event
    listEvents(first: Int, after: String): EventConnection
    getComment(eventId: ID!): Comment
    listComments(first: Int, after: String): CommentConnection
}

type Subscription {
    onCreateEvent(
        id: ID,
        name: String,
        where: String,
        when: String,
        description: String
    ): Event
        @aws_subscribe(mutations: ["createEvent"])
    onUpdateEvent(
        id: ID,
        name: String,
        where: String,
        when: String,
        description: String
    ): Event
        @aws_subscribe(mutations: ["updateEvent"])
    onDeleteEvent(
        id: ID,
        name: String,
        where: String,
        when: String,
        description: String
    ): Event
        @aws_subscribe(mutations: ["deleteEvent"])
    onCreateComment(eventId: ID, commentId: String, content: String): Comment
        @aws_subscribe(mutations: ["createComment"])
    onUpdateComment(eventId: ID, commentId: String, content: String): Comment
        @aws_subscribe(mutations: ["updateComment"])
    onDeleteComment(eventId: ID, commentId: String, content: String): Comment
        @aws_subscribe(mutations: ["deleteComment"])
}

input UpdateCommentInput {
    eventId: ID!
    commentId: String
    content: String
}

input UpdateEventInput {
    id: ID!
    name: String
    where: String
    when: String
    description: String
}

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

Вот как должна выглядеть схема после запуска создания ресурсов для типов событий и комментариев. При прохождении потока «Создание ресурсов» с типом комментария вы должны выбрать eventId в качестве хэш-ключа таблицы и commentId в качестве ключа сортировки. Для типа «Событие» вы можете оставить «id» в качестве единственного хеш-ключа. Так что это для нас сделало?

Сначала он создал 2 таблицы DynamoDB для хранения наших объектов типа «Событие» и «Комментарий». Затем он импортировал эти таблицы как источники данных AppSync и сгенерировал новые части схемы, включая входные объекты, объекты, поля запросов и мутаций, и сохранил их в схеме. Он также подключил преобразователи, специфичные для новой таблицы, которую вы только что определили, и прикрепил их к вновь созданным полям запроса и мутации, которые реализуют общие шаблоны CRUD. К сожалению, он еще не понимает отношения, поэтому мы должны добавить их сами. Для этого давайте сначала сделаем мутацию, чтобы создать отношения, о которых вы просили, и для полноты картины мы также сделаем запрос.

Как вы уже сделали, вам нужно будет добавить что-то подобное в свою схему

type Mutation {
  commentOnEvent(input: CommentOnEventInput!): Comment
}
input CommentOnEventInput {
  eventId: ID!
  content: String
}

Сохраните схему и нажмите «Присоединить» в поле Mutation.commentOnEvent, чтобы добавить преобразователь. Выберите источник данных CommentTable, который мы создали ранее, и в шаблоне сопоставления поместите это:

{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : {
      "eventId": $util.dynamodb.toDynamoDBJson($ctx.args.input.eventId),
      "commentId": $util.dynamodb.toDynamoDBJson($util.autoId()),
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args.input)
}

и для шаблона сопоставления ответов

$util.toJson($context.result)

Нажмите "Сохранить". Теперь у вас должна быть возможность выполнить такой запрос:

mutation {
  commentOnEvent(input: { eventId: "***", content: "A comment"}) {
    eventId
    content
  }
}

Давайте теперь добавим, чтобы прочитать данные через отношение. НАПРИМЕР. Я хочу иметь возможность выполнять такой запрос:

query {
  getEvent(id: "***") {
    id
    comments(first: 5) {
      items {
        content
      }
    }
  }
}

Для этого давайте сначала добавим в схему следующие части.

type Event {
  # add this to existing fields
  comments(first: Int, after: String): CommentConnection
}

Нажмите "Сохранить", затем нажмите "Присоединить" в поле Event.comments. Снова выберите источник данных CommentTable, а затем укажите следующее для шаблона сопоставления запроса.

# Event.comments.request.vtl
{
    "version" : "2017-02-28",
    "operation" : "Query",
    "query" : {
        "expression": "eventId = :eventId",
        "expressionValues" : {
            ":eventId" : {
                "S" : "${ctx.source.id}"
            }
        }
    },
    "limit": $util.defaultIfNull(${ctx.args.first}, 20),
    "nextToken": $util.toJson($util.defaultIfNullOrBlank($ctx.args.after, null))
} 

Обратите внимание на $ ctx.source.id. Поскольку мы разрешаем поле Event.comments, $ ctx.source является экземпляром типа события, для которого мы разрешаем комментарии. Фактически это делает так, что везде, где мы включаем { comments { ... } в набор выбора для типа Мероприятие, будут выбираться только комментарии для родительского события. И затем вы можете вернуть объект результата с разбивкой на страницы.

# Event.comments.response.vtl
# $ctx.result = { items: [...], nextToken: "..." }
$util.toJson($ctx.result)

Это должно помочь. Теперь вы можете запустить оба этих запроса и посмотреть результаты.

mutation {
  commentOnEvent(input: { eventId: "***", content: "A comment"}) {
    eventId
    content
  }
}


query {
  getEvent(id: "***") {
    id
    comments(first: 5) {
      items {
        content
      }
    }
  }
}

Надеюсь это поможет.

спасибо за подробные инструкции, попытку построчно. После настройки таблицы комментариев с помощью распознавателя для установки commentId с помощью autoId () подобная мутация не создает новую строку в таблице комментариев и перезаписывает старую с помощью "id2222" mutation { commentOnEvent(input: { eventId: "id2222", content: "something else comment"}) {eventId content } }

Takeshi Amano 14.07.2018 04:03

и запрос, как показано ниже, дает мне ошибку query { getEvent(id: "id2222") { id comments(first: 5) { items { content } } } }

Takeshi Amano 14.07.2018 04:05

Мне понадобится дополнительная информация, чтобы помочь отладить это. Если у вас есть шаблон преобразователя, указанный выше, и таблица с ключом HASH «eventId» и ключом SORT «commentId», то будет создана новая строка. Я бы дважды проверил, что у вас все настроено правильно. У меня это работает с моей стороны.

mparis 18.07.2018 21:34

Было бы здорово, если бы вы написали об этом в блоге. Информации об отношениях и AppSync не так много, даже в документации.

Pier 03.11.2018 01:02

@ Пьер, я бы мог. Вот несколько новых

mparis 03.11.2018 01:38

К сожалению, нажал слишком рано. Я собирался сказать, вот несколько новых документов по созданию отношений в AppSync с использованием AWS Amplify и директивы @model по преобразованию GraphQL: aws-amplify.github.io/docs/js/graphql#connection

mparis 03.11.2018 01:40

Можно ли использовать эти обозначения @ в обычной схеме AppSync без Amplify?

Pier 03.11.2018 05:45

Нет, это можно использовать только с усилителем. Директивы компилируются в шаблоны преобразователя при сборке проекта Amplify.

mparis 04.11.2018 00:49

Другие вопросы по теме