GraphQL'de girdi türünün amacı nedir?


90

Mutasyonun girdi bağımsız değişkeni nesne ise neden girdi türü olması gerektiğini açıklar mısınız? Bence çok daha basit, kimliği sağlamadan türü yeniden kullanın .

Örneğin:

type Sample {
  id: String
  name: String
}

input SampleInput {
  name: String
}

type RootMutation {
  addSample(sample: Sample): Sample  # <-- instead of it should be
  addSample(sample: SampleInput): Sample
}

Küçük nesneler için sorun değil, ancak şemada 10'dan fazla özelliğe sahip çok sayıda nesneniz olduğunda bu bir yük haline gelecektir.


32
Giriş nesneleri serileştirilebilir olmalıdır. Çıktı nesneleri döngü içerebileceğinden, girdi için yeniden kullanılamazlar.
Jesse Buchanan

1
Jesse, yeterince cevap gibi görünüyor! Cevap verebilirsin ve ben öyle işaretlerim.
Dmitry Dushkin

Yanıtlar:


114

Spesifikasyondan:

GraphQL Nesne türü (ObjectTypeDefinition) ... yeniden kullanım için uygun değildir [girdi olarak], çünkü Nesne türleri bağımsız değişkenleri tanımlayan veya arabirimlere ve birleşimlere referanslar içeren alanlar içerebilir, bunların hiçbiri girdi bağımsız değişkeni olarak kullanılmaya uygun değildir . Bu nedenle, giriş nesnelerinin sistemde ayrı bir türü vardır.

"Resmi neden" budur, ancak bir nesne türünü girdi nesnesi türü olarak veya bir nesne türünü girdi nesnesi türü olarak kullanamamanın birkaç pratik nedeni vardır:

İşlevsellik

Nesne türlerinin ve girdi nesnesi türlerinin her ikisinin de alanları vardır, ancak bu alanlar, bu türlerin şema tarafından nasıl kullanıldığını yansıtan farklı özelliklere sahiptir. Şemanız, bir nesne türünün alanları için potansiyel olarak argümanları ve bir tür çözümleyici işlevi tanımlayacaktır, ancak bu özellikler bir girdi bağlamında anlam ifade etmez (yani bir girdi nesnesinin alanını çözemezsiniz - zaten açık bir değere sahiptir) . Benzer şekilde, varsayılan değerler yalnızca girdi nesne türü alanları için sağlanabilir ve nesne türü alanları için sağlanamaz.

Başka bir deyişle, bu kopya gibi görünebilir:

type Student {
  name: String
  grade: Grade
}

input StudentInput {
  name: String
  grade: Grade
}

Ancak nesne türlerine veya girdi nesnesi türlerine özgü özellikler eklemek, bunların farklı davrandıklarını netleştirir:

type Student {
  name(preferred: Boolean): String
  grade: Grade
}

input StudentInput {
  name: String
  grade: Grade = F
}

Tür sistem sınırlamaları

GraphQL'deki türler, çıktı türleri ve girdi türleri olarak gruplandırılır .

Çıktı türleri, bir GraphQL hizmeti tarafından üretilen bir yanıtın parçası olarak döndürülebilen türlerdir. Giriş türleri, alan veya yönerge bağımsız değişkenleri için geçerli girdiler olan türlerdir.

Bu iki grup arasında örtüşme vardır (yani skalarlar, numaralandırmalar, listeler ve boş olmayanlar). Ancak, birleşimler ve arabirimler gibi soyut türler bir girdi bağlamında anlam ifade etmez ve girdi olarak kullanılamaz. Nesne türlerini ve girdi nesnesi türlerini ayırmak, bir giriş türünün beklendiği durumlarda soyut bir türün asla kullanılmamasını sağlamanıza olanak tanır.

Şema tasarımı

Şemanızda bir varlığı temsil ederken, bazı varlıkların gerçekten de ilgili girdi ve çıktı türleri arasında "alanları paylaşması" muhtemeldir:

type Student {
  firstName: String
  lastName: String
  grade: Grade
}

input StudentInput {
  firstName: String
  lastName: String
  grade: Grade
}

Bununla birlikte, nesne türleri çok karmaşık veri yapılarını modelleyebilir (ve gerçekte sıklıkla yapar):

type Student {
  fullName: String!
  classes: [Class!]!
  address: Address!
  emergencyContact: Contact
  # etc
}

Bu yapılar iken edebilir uygun girişler çevirmek genellikle onlar değil, (biz de onların adresini temsil eden bir nesne geçer yüzden, bir Öğrenci oluşturma) - yani belki sınıf kimliği ve bölüm kimliği değil, bir tarafından öğrencinin derslere belirtmeniz gerekir nesne. Benzer şekilde, geri dönmek istediğimiz, ancak mutasyona uğramak istemediğimiz veya tam tersi (bir passwordalan gibi ) alanlarımız olabilir.

Dahası, nispeten basit varlıklar için bile, nesne türleri ve bunların "karşılık gelen" girdi nesneleri arasındaki boş değer atanabilirlik konusunda genellikle farklı gereksinimlere sahibiz. Genellikle bir alanın yanıtta da döndürüleceğini garanti etmek isteriz, ancak girdimizde aynı alanları zorunlu kılmak istemiyoruz. Örneğin,

type Student {
  firstName: String!
  lastName: String!
}

input StudentInput {
  firstName: String
  lastName: String
}

Son olarak, birçok şemada, belirli bir varlık için nesne türü ile giriş nesnesi türü arasında genellikle bire bir eşleştirme yoktur. Yaygın bir model, şema düzeyinde giriş doğrulamasını daha da ince ayarlamak için farklı işlemler için ayrı giriş nesnesi türlerini kullanmaktır:

input CreateUserInput {
  firstName: String!
  lastName: String!
  email: String!
  password: String!
}

input UpdateUserInput {
  email: String
  password: String
}

Bu örneklerin tümü önemli bir noktayı göstermektedir - bir girdi nesnesi türü bazen bir nesne türünü yansıtabilirken, iş gereksinimleri nedeniyle bunu üretim şemalarında görme olasılığınız çok daha düşüktür.


4
bu gerçekten harika bir cevap!
Charlie Ng

Yanılıyorsam düzeltin ama sizin örneğinizde tür Gradegirdide tekrar kullanılamaz StudentInput, değil mi? Giriş nesnesindeki alanları satır içi yapmanız veya bir GradeInputgiriş nesnesine sahip olmanız gerekir .
Matt

2
@Matt İyi soru! Yukarıdaki örnekte, Gradebir enum türüdür. Nesnelerle farklı olarak, ve çeteleler türleri (String, Int, vb) gibi sayısal tipleri olarak kullanılabilen iki girdi türleri ve çıkış türleri.
Daniel Rearden

güzel açıklama
Visakh Vijayan

Gerçekten harika cevap!
Johnny

25

Jesse'nin yorumu doğru. Daha resmi bir cevap için, girdi türleriyle ilgili GraphQL belgelerinden alıntı :

Yukarıda tanımlanan Nesne türü burada yeniden kullanım için uygun değildir, çünkü Nesneler arabirimlere ve birleşimlere dairesel referanslar veya referanslar ifade eden alanlar içerebilir ve bunların hiçbiri giriş bağımsız değişkeni olarak kullanıma uygun değildir. Bu nedenle, giriş nesnelerinin sistemde ayrı bir türü vardır.

GÜNCELLEME

Gönderdiğimden beri, döngüsel referansların geçersiz olduğu sürece (ya da sonsuz bir zincir ilan edeceği) sürece gerçekten kabul edilebilir olduğunu buldum. Ancak yine de, girişler için ayrı bir tip sistem gerektiriyor gibi görünen başka sınırlamalar (örneğin arayüzler) vardır.


4
Burada bu kısıtlamanın neden var olduğuna
Cam Jackson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.