ডেটা কানেক্ট মিউটেশন বাস্তবায়ন করুন

Firebase Data Connect আপনাকে Google Cloud SQL দ্বারা পরিচালিত আপনার PostgreSQL ইনস্ট্যান্সগুলির জন্য কানেক্টর তৈরি করতে দেয়। এই কানেক্টরগুলি হলো আপনার স্কিমা থেকে ডেটা ব্যবহার করার জন্য কোয়েরি এবং মিউটেশনের সমন্বয়।

গেট স্টার্টেড গাইডটিতে PostgreSQL-এর জন্য একটি মুভি রিভিউ অ্যাপ স্কিমা উপস্থাপন করা হয়েছে।

সেই নির্দেশিকাটিতে মিউটেশন সহ স্থাপনযোগ্য এবং অ্যাড-হক উভয় ধরনের প্রশাসনিক অপারেশনেরও সূচনা করা হয়েছিল।

  • ডিপ্লয়েবল মিউটেশন হলো সেগুলো, যা আপনি একটি কানেক্টরের মধ্যে ক্লায়েন্ট অ্যাপ থেকে কল করার জন্য ইমপ্লিমেন্ট করেন এবং যার এপিআই এন্ডপয়েন্টগুলো আপনিই নির্ধারণ করেন। Data Connect এই মিউটেশনগুলোর মধ্যে অথেনটিকেশন ও অথরাইজেশন একীভূত করে এবং আপনার এপিআই-এর উপর ভিত্তি করে ক্লায়েন্ট এসডিকে তৈরি করে।
  • টেবিল পূরণ ও পরিচালনা করার জন্য বিশেষ প্রশাসনিক পরিবর্তনগুলো বিশেষাধিকারপ্রাপ্ত পরিবেশ থেকে চালানো হয়। আপনি এগুলো Firebase কনসোলে, Firebase Admin SDK ব্যবহার করে বিশেষাধিকারপ্রাপ্ত পরিবেশ থেকে, এবং আমাদের Data Connect VS Code এক্সটেনশন ব্যবহার করে স্থানীয় ডেভেলপমেন্ট পরিবেশে তৈরি ও কার্যকর করতে পারেন।

এই নির্দেশিকাটি স্থাপনযোগ্য মিউটেশনগুলো নিয়ে আরও গভীরভাবে আলোচনা করে।

Data Connect মিউটেশনের বৈশিষ্ট্য

Data Connect আপনাকে একটি PostgreSQL ডাটাবেসে প্রত্যাশিত সমস্ত উপায়ে মৌলিক পরিবর্তনগুলি সম্পাদন করার সুযোগ দেয়:

  • CRUD অপারেশন সম্পাদন করুন
  • ট্রানজ্যাকশনের মাধ্যমে বহু-ধাপের কার্যক্রম পরিচালনা করুন

কিন্তু Data Connect এর GraphQL এক্সটেনশনগুলির সাহায্যে, আপনি আরও দ্রুত ও কার্যকর অ্যাপের জন্য উন্নত মিউটেশন প্রয়োগ করতে পারেন:

  • রেকর্ডের উপর পুনরাবৃত্তিমূলক অপারেশন সহজ করার জন্য অনেক অপারেশন দ্বারা ফেরত আসা কী স্কেলার ব্যবহার করুন।
  • সার্ভার কর্তৃক প্রদত্ত অপারেশন ব্যবহার করে সার্ভারের মান দিয়ে ডেটা পূরণ করুন।
  • একাধিক ধাপের মিউটেশন অপারেশন চলাকালীন ডেটা খোঁজার জন্য কোয়েরি সম্পাদন করুন, যা কোডের লাইন এবং সার্ভারে রাউন্ড ট্রিপ বাঁচায়।

মিউটেশন বাস্তবায়নের জন্য জেনারেটেড ফিল্ড ব্যবহার করুন

আপনার Data Connect অপারেশনগুলো আপনার স্কিমার টাইপ এবং টাইপ সম্পর্কের উপর ভিত্তি করে Data Connect দ্বারা স্বয়ংক্রিয়ভাবে তৈরি হওয়া এক সেট ফিল্ডকে প্রসারিত করবে। যখনই আপনি আপনার স্কিমা সম্পাদনা করেন, স্থানীয় টুলিং দ্বারা এই ফিল্ডগুলো তৈরি হয়।

আপনি জেনারেটেড ফিল্ড ব্যবহার করে মিউটেশন বাস্তবায়ন করতে পারেন, যেমন—একটি টেবিলের স্বতন্ত্র রেকর্ড তৈরি, আপডেট ও ডিলিট করা থেকে শুরু করে আরও জটিল একাধিক-টেবিল আপডেট পর্যন্ত।

ধরে নিন আপনার স্কিমাতে একটি Movie টাইপ এবং এর সাথে যুক্ত একটি Actor টাইপ রয়েছে। Data Connect movie_insert , movie_update , movie_delete ফিল্ড এবং আরও অনেক কিছু তৈরি করে।

মিউটেশনের সাথে
movie_insert ফিল্ড

movie_insert ফিল্ডটি Movie টেবিলে একটি একক রেকর্ড তৈরি করার জন্য একটি পরিবর্তনকে নির্দেশ করে।

একটিমাত্র মুভি তৈরি করতে এই ফিল্ডটি ব্যবহার করুন।

mutation CreateMovie($data: Movie_Data!) {
  movie_insert(data: $data) { key }
}

মিউটেশনের সাথে
movie_update ফিল্ড

movie_update ফিল্ডটি ` Movie টেবিলের একটিমাত্র রেকর্ড আপডেট করার জন্য একটি মিউটেশনকে নির্দেশ করে।

এর কী (key) ব্যবহার করে যেকোনো একটি মুভি আপডেট করতে এই ফিল্ডটি ব্যবহার করুন।

mutation UpdateMovie($myKey: Movie_Key!, $data: Movie_Data!) {
  movie_update(key: $myKey, data: $data) { key }
}

মিউটেশনের সাথে
movie_delete ফিল্ড

movie_delete ফিল্ডটি ` Movie টেবিলের একটিমাত্র রেকর্ড মুছে ফেলার জন্য একটি মিউটেশনকে নির্দেশ করে।

এর কী (key) ব্যবহার করে কোনো একটি মুভি ডিলিট করতে এই ফিল্ডটি ব্যবহার করুন।

  mutation DeleteMovie($myKey: Movie_Key!) {
    movie_delete(key: $myKey) { key }
  }

মিউটেশনের অপরিহার্য উপাদানসমূহ

Data Connect মিউটেশন হলো Data Connect এক্সটেনশনসহ গ্রাফকিউএল মিউটেশন। একটি সাধারণ গ্রাফকিউএল মিউটেশনের মতোই, আপনি একটি অপারেশন নাম এবং গ্রাফকিউএল ভেরিয়েবলের একটি তালিকা নির্ধারণ করতে পারেন।

Data Connect @auth এবং @transaction মতো কাস্টমাইজড ডিরেক্টিভ ব্যবহার করে GraphQL কোয়েরিগুলোকে আরও উন্নত করে।

সুতরাং নিম্নলিখিত মিউটেশনটি হলো:

  • একটি mutation প্রকারের সংজ্ঞা
  • একটি SignUp অপারেশন (মিউটেশন) নাম
  • একটি একক ভেরিয়েবল $username অপারেশন আর্গুমেন্ট
  • একটিমাত্র নির্দেশিকা, @auth
  • একটি একক ফিল্ড user_insert
mutation SignUp($username: String!) @auth(level: USER) {
  user_insert(data: {
    id_expr: "auth.uid"
    username: $username
  })
}

প্রতিটি মিউটেশন আর্গুমেন্টের জন্য একটি টাইপ ডিক্লারেশন প্রয়োজন, যেমন String মতো একটি বিল্ট-ইন টাইপ, অথবা Movie মতো একটি কাস্টম, স্কিমা-সংজ্ঞায়িত টাইপ।

মৌলিক মিউটেশন লিখুন

আপনি আপনার ডাটাবেস থেকে স্বতন্ত্র রেকর্ড তৈরি, আপডেট এবং মুছে ফেলার জন্য মিউটেশন লেখা শুরু করতে পারেন।

তৈরি করুন

চলুন সাধারণ কিছু জিনিস তৈরি করি।

# Create a movie based on user input
mutation CreateMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) {
  movie_insert(data: {
    title: $title
    releaseYear: $releaseYear
    genre: $genre
    rating: $rating
  })
}

# Create a movie with default values
mutation CreateMovie2 {
  movie_insert(data: {
    title: "Sherlock Holmes"
    releaseYear: 2009
    genre: "Mystery"
    rating: 5
  })
}

অথবা একটি আপসার্ট।

# Movie upsert using combination of variables and literals
mutation UpsertMovie($title: String!) {
  movie_upsert(data: {
    title: $title
    releaseYear: 2009
    genre: "Mystery"
    rating: 5
    genre: "Mystery/Thriller"
  })
}

আপডেটগুলি সম্পাদন করুন

এই হলো সর্বশেষ তথ্য। প্রযোজক ও পরিচালকেরা অবশ্যই আশা করছেন যে এই গড় রেটিংগুলো একটি চলমান ধারা।

movie_update ফিল্ডটিতে একটি রেকর্ড শনাক্ত করার জন্য প্রত্যাশিত id আর্গুমেন্ট এবং এই আপডেটে মান নির্ধারণের জন্য একটি data ফিল্ড থাকে।

mutation UpdateMovie(
  $id: UUID!,
  $genre: String!,
  $rating: Int!,
  $description: String!
) {
  movie_update(id: $id,
    data: {
      genre: $genre
      rating: $rating
      description: $description
    })
}

একাধিক আপডেট করার জন্য movie_updateMany ফিল্ডটি ব্যবহার করুন।

# Multiple updates (increase all ratings of a genre)
mutation IncreaseRatingForGenre($genre: String!, $rating: Int!) {
  movie_updateMany(
    where: { genre: { eq: $genre } },
    data:
      {
        rating: $rating
      })
}

_update সাথে increment, decrement, append, এবং prepend অপারেশনগুলো ব্যবহার করুন।

যদিও _update এবং _updateMany মিউটেশনগুলিতে আপনি data: মধ্যে স্পষ্টভাবে মান সেট করতে পারেন, মান আপডেট করার জন্য increment-এর মতো কোনো অপারেটর প্রয়োগ করাই প্রায়শই বেশি যুক্তিযুক্ত।

পূর্ববর্তী আপডেট উদাহরণটি পরিবর্তন করতে, ধরে নিন আপনি একটি নির্দিষ্ট সিনেমার রেটিং বাড়াতে চান। আপনি inc অপারেটরের সাথে rating_update সিনট্যাক্স ব্যবহার করতে পারেন।

mutation UpdateMovie(
  $id: UUID!,
  $ratingIncrement: Int!
) {
  movie_update(id: $id, data: {
    rating_update: {
      inc: $ratingIncrement
    }
  })
}

Data Connect ফিল্ড আপডেটের জন্য নিম্নলিখিত অপারেটরগুলিকে সমর্থন করে:

  • Int , Int64 , Float , Date এবং Timestamp ডেটা টাইপের মান বৃদ্ধি করতে inc করা হয়।
  • Int , Int64 , Float , Date এবং Timestamp ডেটা টাইপের মান কমানো dec

তালিকার ক্ষেত্রে, আপনি নিম্নলিখিত পদ্ধতি ব্যবহার করে স্বতন্ত্র মান অথবা মানের তালিকা দিয়েও আপডেট করতে পারেন:

  • ভেক্টর লিস্ট ব্যতীত অন্যান্য লিস্ট টাইপে, যদি আইটেম(গুলি) আগে থেকে উপস্থিত না থাকে, তবে সেগুলি add
  • ভেক্টর লিস্ট ব্যতীত অন্য সব ধরনের লিস্ট থেকে, যদি থাকে, সমস্ত আইটেম মুছে ফেলার জন্য remove
  • ভেক্টর লিস্ট ব্যতীত অন্যান্য লিস্ট টাইপে আইটেম append করতে `append` ব্যবহার করুন।
  • ভেক্টর তালিকা ব্যতীত অন্যান্য তালিকার প্রকারের শুরুতে আইটেম যুক্ত করতে prepend

মুছে ফেলার কাজ সম্পাদন করুন

আপনি অবশ্যই সিনেমার ডেটা মুছে ফেলতে পারেন। চলচ্চিত্র সংরক্ষণকারীরা অবশ্যই চাইবেন যে মূল ফিল্মগুলো যত দিন সম্ভব সংরক্ষণ করা হোক।

# Delete by key
mutation DeleteMovie($id: UUID!) {
  movie_delete(id: $id)
}

এখানে আপনি _deleteMany ব্যবহার করতে পারেন।

# Multiple deletes
mutation DeleteUnpopularMovies($minRating: Int!) {
  movie_deleteMany(where: { rating: { le: $minRating } })
}

সম্পর্কগুলিতে পরিবর্তন লিখুন

একটি রিলেশনে ইমপ্লিসিট _upsert মিউটেশন কীভাবে ব্যবহার করতে হয় তা লক্ষ্য করুন।

# Create or update a one to one relation
mutation MovieMetadataUpsert($movieId: UUID!, $director: String!) {
  movieMetadata_upsert(
    data: { movie: { id: $movieId }, director: $director }
  )
}

দক্ষ মিউটেশনের জন্য ডিজাইন স্কিমা

Data Connect দুটি গুরুত্বপূর্ণ বৈশিষ্ট্য প্রদান করে, যা আপনাকে আরও কার্যকর মিউটেশন লিখতে এবং রাউন্ড-ট্রিপ অপারেশন বাঁচাতে সাহায্য করে।

কী স্কেলার হলো সংক্ষিপ্ত অবজেক্ট আইডেন্টিফায়ার যা Data Connect আপনার স্কিমার কী ফিল্ডগুলো থেকে স্বয়ংক্রিয়ভাবে তৈরি করে। কী স্কেলারের মূল উদ্দেশ্য হলো কার্যকারিতা বৃদ্ধি করা, যা আপনাকে একটিমাত্র কলের মাধ্যমেই আপনার ডেটার পরিচয় এবং কাঠামো সম্পর্কিত তথ্য খুঁজে পেতে সাহায্য করে। এগুলি বিশেষভাবে উপযোগী যখন আপনি নতুন রেকর্ডের উপর ধারাবাহিক কাজ সম্পাদন করতে চান এবং পরবর্তী অপারেশনগুলিতে পাঠানোর জন্য একটি অনন্য আইডেন্টিফায়ারের প্রয়োজন হয়, এবং যখন আপনি অতিরিক্ত ও আরও জটিল অপারেশন সম্পাদনের জন্য রিলেশনাল কী অ্যাক্সেস করতে চান।

সার্ভার ভ্যালু ব্যবহার করে, আপনি expr আর্গুমেন্টে থাকা নির্দিষ্ট সার্ভার-সাইড CEL এক্সপ্রেশন অনুযায়ী সংরক্ষিত বা সহজে গণনাযোগ্য ভ্যালু ব্যবহার করে সার্ভারকে আপনার টেবিলের ফিল্ডগুলো ডায়নামিকভাবে পূরণ করতে দিতে পারেন। উদাহরণস্বরূপ, আপনি একটি অপারেশন রিকোয়েস্টে সংরক্ষিত সময় ব্যবহার করে এমন একটি ফিল্ড সংজ্ঞায়িত করতে পারেন যেখানে ফিল্ডটি অ্যাক্সেস করার সময় একটি টাইমস্ট্যাম্প প্রয়োগ করা হয়, updatedAt: Timestamp! @default(expr: "request.time")

উন্নত মিউটেশন লিখুন: Data Connect field_expr সিনট্যাক্স ব্যবহার করে ভ্যালু সরবরাহ করতে দিন।

মূল স্কেলার এবং সার্ভার ভ্যালু অংশে যেমন আলোচনা করা হয়েছে, আপনি আপনার স্কিমাটি এমনভাবে ডিজাইন করতে পারেন যাতে সার্ভার ক্লায়েন্টের অনুরোধের জবাবে id এবং তারিখের মতো সাধারণ ফিল্ডগুলির ভ্যালু পূরণ করে দেয়।

এছাড়াও, আপনি ক্লায়েন্ট অ্যাপ থেকে Data Connect request অবজেক্টে পাঠানো ইউজার আইডির মতো ডেটা ব্যবহার করতে পারেন।

মিউটেশন প্রয়োগ করার সময়, সার্ভার-জেনারেটেড আপডেট ট্রিগার করতে বা রিকোয়েস্ট থেকে ডেটা অ্যাক্সেস করতে field_expr সিনট্যাক্স ব্যবহার করুন। উদাহরণস্বরূপ, একটি _upsert অপারেশনে কোনো রিকোয়েস্টে সংরক্ষিত অথরাইজেশন uid পাস করতে, userId_expr ফিল্ডে "auth.uid" পাস করুন।

# Add a movie to the user's favorites list
mutation AddFavoritedMovie($movieId: UUID!) @auth(level: USER) {
  favorite_movie_upsert(data: { userId_expr: "auth.uid", movieId: $movieId })
}

# Remove a movie from the user's favorites list
mutation DeleteFavoritedMovie($movieId: UUID!) @auth(level: USER) {
  favorite_movie_delete(key: { userId_expr: "auth.uid", movieId: $movieId })
}

অথবা, একটি পরিচিত টু-ডু লিস্ট অ্যাপে, নতুন টু-ডু লিস্ট তৈরি করার সময়, আপনি id_expr পাস করে সার্ভারকে লিস্টটির জন্য স্বয়ংক্রিয়ভাবে একটি UUID তৈরি করার নির্দেশ দিতে পারেন।

mutation CreateTodoListWithFirstItem(
  $listName: String!
) @transaction {
  # Step 1
  todoList_insert(data: {
    id_expr: "uuidV4()", # <-- auto-generated. Or a column-level @default on `type TodoList` will also work
    name: $listName,
  })
}

আরও তথ্যের জন্য, স্কেলার রেফারেন্সে _Expr স্কেলারগুলো দেখুন।

উন্নত মিউটেশন লিখুন: বহু-ধাপ অপারেশন

এমন অনেক পরিস্থিতি আছে যেখানে আপনি একটি মিউটেশনের মধ্যে একাধিক রাইট ফিল্ড (যেমন ইনসার্ট) অন্তর্ভুক্ত করতে চাইতে পারেন। এছাড়াও, উদাহরণস্বরূপ, ইনসার্ট বা আপডেট করার আগে বিদ্যমান ডেটা খুঁজে বের করতে ও যাচাই করার জন্য আপনি একটি মিউটেশন চলাকালীন আপনার ডাটাবেস পড়তে চাইতে পারেন। এই বিকল্পগুলো রাউন্ড ট্রিপ অপারেশন এবং ফলস্বরূপ খরচ বাঁচায়।

Data Connect নিম্নলিখিত বিষয়গুলো সমর্থন করার মাধ্যমে আপনার মিউটেশনগুলিতে বহু-ধাপের লজিক সম্পাদন করতে দেয়:

  • একাধিক লেখার ক্ষেত্র

  • আপনার মিউটেশনগুলিতে একাধিক রিড ফিল্ড ( query ফিল্ড কীওয়ার্ড ব্যবহার করে)।

  • @transaction ডিরেক্টিভ , যা রিলেশনাল ডেটাবেস থেকে পরিচিত ট্রানজ্যাকশন সাপোর্ট প্রদান করে।

  • @check ডিরেক্টিভটি , যা আপনাকে CEL এক্সপ্রেশন ব্যবহার করে রিডের বিষয়বস্তু মূল্যায়ন করতে দেয়, এবং এই ধরনের মূল্যায়নের ফলাফলের উপর ভিত্তি করে:

    • মিউটেশন দ্বারা সংজ্ঞায়িত তৈরি, আপডেট এবং মুছে ফেলার কাজ চালিয়ে যান।
    • কোয়েরি ফিল্ডের ফলাফল ফেরত দিতে অগ্রসর হোন।
    • আপনার ক্লায়েন্ট কোডে যথাযথ লজিক প্রয়োগ করতে ফেরত আসা বার্তাগুলো ব্যবহার করুন।
  • @redact ডিরেক্টিভটি , যা আপনাকে ওয়্যার প্রোটোকল ফলাফল থেকে কোয়েরি ফিল্ডের ফলাফল বাদ দিতে দেয়।

  • CEL response বাইন্ডিং, যা একটি জটিল, বহু-ধাপের অপারেশনে সম্পাদিত সমস্ত মিউটেশন এবং কোয়েরির সঞ্চিত ফলাফল সংরক্ষণ করে। আপনি response বাইন্ডিংটি অ্যাক্সেস করতে পারেন:

    • @check ডিরেক্টিভে, expr: আর্গুমেন্টের মাধ্যমে
    • সার্ভার মানগুলির সাথে, field_expr সিনট্যাক্স ব্যবহার করে

@transaction নির্দেশিকা

একাধিক ধাপের পরিবর্তনের জন্য সহায়তার মধ্যে ট্রানজ্যাকশন ব্যবহার করে ত্রুটি পরিচালনা অন্তর্ভুক্ত রয়েছে।

@transaction ডিরেক্টিভটি নিশ্চিত করে যে, একটি মিউটেশন—তাতে একটিমাত্র রাইট ফিল্ড (যেমন, _insert বা _update ) থাকুক বা একাধিক রাইট ফিল্ড থাকুক—সর্বদা একটি ডাটাবেস ট্রানজ্যাকশনের মধ্যে রান করে।

  • @transaction ছাড়া মিউটেশনগুলো প্রতিটি রুট ফিল্ডকে ক্রমানুসারে একের পর এক এক্সিকিউট করে। অপারেশনটি যেকোনো ত্রুটিকে আংশিক ফিল্ড ত্রুটি হিসেবে প্রকাশ করে, কিন্তু পরবর্তী এক্সিকিউশনগুলোর প্রভাব প্রকাশ করে না।

  • @transaction সহ পরিবর্তনগুলি সম্পূর্ণরূপে সফল বা সম্পূর্ণরূপে ব্যর্থ হবেই। যদি ট্রানজ্যাকশনের অন্তর্ভুক্ত কোনো ফিল্ড ব্যর্থ হয়, তবে সম্পূর্ণ ট্রানজ্যাকশনটি রোলব্যাক করা হয়।

@check এবং @redact নির্দেশাবলী

@check ডিরেক্টিভটি কোয়েরির ফলাফলে নির্দিষ্ট ফিল্ডগুলো উপস্থিত আছে কিনা তা যাচাই করে। ফিল্ডের মান পরীক্ষা করার জন্য একটি কমন এক্সপ্রেশন ল্যাঙ্গুয়েজ (CEL) এক্সপ্রেশন ব্যবহার করা হয়। এই ডিরেক্টিভের ডিফল্ট আচরণ হলো সেইসব নোড খুঁজে বের করা এবং বাতিল করা, যাদের মান null বা [] (খালি তালিকা)।

@redact ডিরেক্টিভটি ক্লায়েন্টের প্রতিক্রিয়া থেকে একটি অংশ মুছে ফেলে। মুছে ফেলা ফিল্ডগুলি সাইড এফেক্টের (ডেটা পরিবর্তন এবং @check সহ) জন্য মূল্যায়ন করা হয় এবং ফলাফলগুলি CEL এক্সপ্রেশনের পরবর্তী ধাপগুলির জন্য উপলব্ধ থাকে।

@check , @check(message:) এবং @redact ব্যবহার করুন

@check এবং @redact এর একটি প্রধান ব্যবহার হলো, নির্দিষ্ট কোনো অপারেশন অনুমোদিত হবে কি না, সেই সিদ্ধান্ত নেওয়ার জন্য প্রাসঙ্গিক ডেটা খুঁজে বের করা। এক্ষেত্রে লজিকের মধ্যেই লুকআপ প্রক্রিয়াটি ব্যবহার করা হয়, কিন্তু ক্লায়েন্টদের কাছ থেকে তা গোপন রাখা হয়। আপনার কোয়েরিটি ক্লায়েন্ট কোডে সঠিক ব্যবস্থাপনার জন্য প্রয়োজনীয় মেসেজ ফেরত দিতে পারে।

উদাহরণস্বরূপ, নিম্নলিখিত কোয়েরি ফিল্ডটি যাচাই করে দেখে যে, কোনো অনুরোধকারীর একটি মুভি সম্পাদনা করতে পারে এমন ব্যবহারকারীদের দেখার জন্য উপযুক্ত "অ্যাডমিন" ভূমিকা আছে কি না।

query GetMovieEditors($movieId: UUID!) @auth(level: USER) {
  moviePermission(key: { movieId: $movieId, userId_expr: "auth.uid" }) @redact {
    role @check(expr: "this == 'admin'", message: "You must be an admin to view all editors of a movie.")
  }
  moviePermissions(where: { movieId: { eq: $movieId }, role: { eq: "editor" } }) {
    user {
      id
      username
    }
  }
}

অনুমোদন যাচাইয়ে @check এবং @redact নির্দেশাবলী সম্পর্কে আরও জানতে, অনুমোদন ডেটা অনুসন্ধান (authorization data lookup) সম্পর্কিত আলোচনাটি দেখুন।

কীগুলো যাচাই করতে @check ব্যবহার করুন

কিছু মিউটেশন ফিল্ড, যেমন _update , কোনো নির্দিষ্ট কী-সহ রেকর্ড বিদ্যমান না থাকলে কোনো কাজ নাও করতে পারে। একইভাবে, লুকআপগুলো null বা একটি খালি তালিকা রিটার্ন করতে পারে। এগুলোকে ত্রুটি হিসেবে গণ্য করা হয় না এবং তাই এগুলো রোলব্যাক ট্রিগার করবে না।

এই ফলাফল এড়ানোর জন্য, @check ডিরেক্টিভ ব্যবহার করে কী-গুলো খুঁজে পাওয়া যায় কিনা তা পরীক্ষা করুন।

# Delete by key, error if not found
mutation MustDeleteMovie($id: UUID!) @transaction {
  movie_delete(id: $id) @check(expr: "this != null", message: "Movie not found, therefore nothing is deleted")
}

বহু-ধাপ মিউটেশন শৃঙ্খলিত করতে response বাইন্ডিং ব্যবহার করুন।

সম্পর্কিত রেকর্ড তৈরি করার মৌলিক পদ্ধতি, যেমন একটি নতুন Movie এবং এর সাথে একটি MovieMetadata এন্ট্রি তৈরি করা, হলো:

  1. Movie জন্য একটি _insert মিউটেশন কল করুন
  2. তৈরি করা মুভিটির ফেরত আসা কী-টি সংরক্ষণ করুন।
  3. এরপর, MovieMetadata রেকর্ডটি তৈরি করার জন্য দ্বিতীয় একটি _insert মিউটেশন কল করুন।

কিন্তু Data Connect সাহায্যে, আপনি দ্বিতীয় _insert এ প্রথম _insert এর ফলাফল অ্যাক্সেস করার মাধ্যমে এই সাধারণ পরিস্থিতিটি একটি একক বহু-ধাপের অপারেশনেই সমাধান করতে পারেন।

একটি সফল মুভি রিভিউ অ্যাপ তৈরি করা অনেক পরিশ্রমের কাজ। চলুন একটি নতুন উদাহরণের মাধ্যমে আমাদের করণীয় কাজের তালিকাটি দেখে নেওয়া যাক।

সার্ভার মান দিয়ে ফিল্ড সেট করতে response ব্যবহার করুন।

নিম্নলিখিত করণীয় তালিকার পরিবর্তনে:

  • response বাইন্ডিং এখন পর্যন্ত আংশিক রেসপন্স অবজেক্টটিকে উপস্থাপন করে, যার মধ্যে বর্তমানটির আগের সমস্ত শীর্ষ-স্তরের মিউটেশন ফিল্ড অন্তর্ভুক্ত থাকে।
  • প্রাথমিক todoList_insert অপারেশনের ফলাফল, যা id (key) ফিল্ডটি রিটার্ন করে, তা পরবর্তীতে response.todoList_insert.id তে অ্যাক্সেস করা হয়, যাতে আমরা অবিলম্বে একটি নতুন টু-ডু আইটেম ইনসার্ট করতে পারি।
mutation CreateTodoListWithFirstItem(
  $listName: String!,
  $itemContent: String!
) @transaction {
  # Sub-step 1:
  todoList_insert(data: {
    id_expr: "uuidV4()", # <-- auto-generated. Or a column-level @default on `type TodoList` will also work
    name: $listName,
  })
  # Sub-step 2:
  todo_insert(data: {
    listId_expr: "response.todoList_insert.id" # <-- Grab the newly generated ID from the partial response so far.
    content: $itemContent,
  })
}

@check ব্যবহার করে response মাধ্যমে ফিল্ডগুলো যাচাই করুন।

@check(expr: "...") -এও response পাওয়া যায়, তাই এটি ব্যবহার করে আপনি আরও জটিল সার্ভার-সাইড লজিক তৈরি করতে পারেন। মিউটেশন-এর query { … } স্টেপগুলোর সাথে একত্রিত করলে, কোনো অতিরিক্ত ক্লায়েন্ট-সার্ভার রাউন্ডট্রিপ ছাড়াই আপনি আরও অনেক কিছু অর্জন করতে পারবেন।

নিম্নলিখিত উদাহরণে লক্ষ্য করুন: @check এর কাছে ইতিমধ্যেই response.query এর অ্যাক্সেস আছে, কারণ একটি @check সর্বদা সেই স্টেপের পরে রান করে যার সাথে এটি সংযুক্ত থাকে।

mutation CreateTodoInNamedList(
  $listName: String!,
  $itemContent: String!
) @transaction {
  # Sub-step 1: Look up List.id by its name
  query
  @check(expr: "response.query.todoLists.size() > 0", message: "No such TodoList with the name!")
  @check(expr: "response.query.todoLists.size() < 2", message: "Ambiguous listName!") {
    todoLists(where: { name: $listName }) {
      id
    }
  }
  # Sub-step 2:
  todo_insert(data: {
    listId_expr: "response.todoLists[0].id" # <-- Now we have the parent list ID to insert to
    content: $itemContent,
  })
}

response বাইন্ডিং সম্পর্কে আরও তথ্যের জন্য, সিইএল রেফারেন্স দেখুন।

@transaction এবং query @check ব্যবহার করে বাধাগ্রস্ত অপারেশনগুলো বুঝুন।

বহু-ধাপের মিউটেশনে ত্রুটি দেখা দিতে পারে:

  • ডাটাবেস অপারেশন ব্যর্থ হতে পারে।
  • কোয়েরি @check লজিক অপারেশন বন্ধ করে দিতে পারে।

Data Connect আপনার মাল্টি-স্টেপ মিউটেশনগুলির সাথে @transaction ডিরেক্টিভটি ব্যবহার করার পরামর্শ দেয়। এর ফলে ডাটাবেস এবং মিউটেশনের ফলাফল আরও সামঞ্জস্যপূর্ণ হয়, যা ক্লায়েন্ট কোডে পরিচালনা করা সহজ হয়।

  • প্রথম ত্রুটি বা @check ব্যর্থ হলেই অপারেশনটি বন্ধ হয়ে যাবে, তাই পরবর্তী কোনো ফিল্ডের এক্সিকিউশন বা CEL-এর ইভ্যালুয়েশন পরিচালনা করার প্রয়োজন নেই।
  • ডাটাবেস ত্রুটি অথবা @check লজিকের প্রতিক্রিয়ায় রোলব্যাক সম্পাদিত হয়, যা ডাটাবেসের একটি সামঞ্জস্যপূর্ণ অবস্থা নিশ্চিত করে।
  • ক্লায়েন্ট কোডে সর্বদা একটি রোলব্যাক ত্রুটি ফেরত পাঠানো হয়।

এমন কিছু ব্যবহারের ক্ষেত্র থাকতে পারে যেখানে আপনি @transaction ব্যবহার না করার সিদ্ধান্ত নিতে পারেন: উদাহরণস্বরূপ, যদি আপনার উচ্চতর থ্রুপুট, স্কেলেবিলিটি বা অ্যাভেইলেবিলিটির প্রয়োজন হয়, তবে আপনি ইভেনচুয়াল কনসিসটেন্সি বেছে নিতে পারেন। তবে, এর ফলাফল কার্যকর করার জন্য আপনাকে আপনার ডাটাবেস এবং ক্লায়েন্ট কোড পরিচালনা করতে হবে।

  • ডাটাবেস অপারেশনের কারণে কোনো একটি ফিল্ড ব্যর্থ হলে, পরবর্তী ফিল্ডগুলো কার্যকর হতে থাকবে। তবে, ব্যর্থ @check সম্পূর্ণ অপারেশনটি বন্ধ করে দেয়।
  • রোলব্যাক করা হয় না, যার ফলে ডাটাবেসের অবস্থা মিশ্র থাকে, যেখানে কিছু আপডেট সফল এবং কিছু ব্যর্থ হয়।
  • আপনার @check লজিক যদি পূর্ববর্তী ধাপের রিড এবং/অথবা রাইট-এর ফলাফল ব্যবহার করে, তাহলে @check এর সাথে আপনার অপারেশনগুলো আরও অসামঞ্জস্যপূর্ণ ফলাফল দিতে পারে।
  • ক্লায়েন্ট কোডে ফেরত পাঠানো ফলাফলে পরিচালনা করার জন্য সাফল্য এবং ব্যর্থতার আরও জটিল মিশ্রণ থাকবে।

Data Connect পরিবর্তনের জন্য নির্দেশাবলী

টাইপ এবং টেবিল সংজ্ঞায়িত করার জন্য ব্যবহৃত নির্দেশাবলী ছাড়াও, Data Connect অপারেশনগুলির আচরণ উন্নত করার জন্য @auth , @check , @redact এবং @transaction নির্দেশাবলী প্রদান করে।

নির্দেশিকা প্রযোজ্য বর্ণনা
@auth কোয়েরি এবং মিউটেশন একটি কোয়েরি বা মিউটেশনের জন্য অনুমোদন নীতি নির্ধারণ করে। অনুমোদন ও প্রত্যয়ন নির্দেশিকা দেখুন।
@check বহু-ধাপ অপারেশনে query ক্ষেত্র কোয়েরির ফলাফলে নির্দিষ্ট ফিল্ডগুলো উপস্থিত আছে কিনা তা যাচাই করে। ফিল্ডের মান পরীক্ষা করার জন্য একটি কমন এক্সপ্রেশন ল্যাঙ্গুয়েজ (CEL) এক্সপ্রেশন ব্যবহার করা হয়। বহু-ধাপীয় অপারেশন দেখুন।
@redact প্রশ্ন ক্লায়েন্টের প্রতিক্রিয়ার একটি অংশ গোপন করে। বহু-ধাপের কার্যক্রম দেখুন।
@transaction মিউটেশন এটি নিশ্চিত করে যে একটি মিউটেশন সর্বদা একটি ডাটাবেস ট্রানজ্যাকশনের মধ্যে চলে। বহু-ধাপ অপারেশন দেখুন।

পরবর্তী পদক্ষেপ

আপনি নিম্নলিখিত বিষয়গুলিতে আগ্রহী হতে পারেন: