Uzun bir sorgu yazmadan tüm GraphQL türü alanları nasıl sorgulayabilirim?


131

Bir GraphQL türünüz olduğunu ve birçok alan içerdiğini varsayalım. Tüm alanların adlarını içeren uzun bir sorgu yazmadan tüm alanları nasıl sorgulayabilirim?

Örneğin, şu alanlar varsa:

 public function fields()
    {
        return [
            'id' => [
                'type' => Type::nonNull(Type::string()),
                'description' => 'The id of the user'
            ],
            'username' => [
                'type' => Type::string(),
                'description' => 'The email of user'
            ], 
             'count' => [
                'type' => Type::int(),
                'description' => 'login count for the user'
            ]

        ];
    }

Tüm alanları sorgulamak için genellikle sorgu şuna benzer:

FetchUsers{users(id:"2"){id,username,count}}

Ama tüm alanları yazmadan aynı sonuçları elde etmenin bir yolunu istiyorum, bunun gibi bir şey:

FetchUsers{users(id:"2"){*}}
//or
FetchUsers{users(id:"2")}

Bunu GraphQL'de yapmanın bir yolu var mı?

Ben kullanıyorum Folkloreatelier / laravel-graphql kütüphane.


4
GraphQL'in tasarım gereği desteklemediği bir şeyin nasıl yapılacağını soruyorsunuz.
Travis Webb

12
Sadece bu 40 şey alanına yazın ve yazım hatası yapmayacağınızı umuyoruz :)
Ska

33
Vay canına, GraphQL ile yeni başlıyorum ve bu ciddi bir WTF.
user949300

1
Desteklenmediği mantıklıdır, Öğrenci ve Sınıf nesneleriniz olduğunu hayal edin, öğrencinin katıldığı tüm sınıfları listeleyen alan "sınıfları" olduğunu, sınıfta o sınıfa katılan tüm öğrencileri listeleyen alan "öğrencileri" olduğunu düşünün. Bu döngüsel bir yapıdır. Şimdi, tüm alanlara sahip tüm öğrenciler için talep ederseniz, bu, döndürülen tüm sınıf alanlarını da içerir mi? Ve bu sınıfların öğrencileri var, alanları da dahil edilir mi? Ve öğrencilerin dersleri var, ...
Buksy

Bu soruyu sormuştum ve o yüzden neyin çekilebileceğini görebiliyordum. Pek çok GraphQL istemcisi (örneğin, GraphiQL, bkz. Gatsbyjs.org/docs/running-queries-with-graphiql ), iç gözlemi kullanarak size çekebileceklerinizi sunmak için iç gözlemi kullanan bir şema gezgini vardır. ".
James

Yanıtlar:


121

Ne yazık ki yapmak istediğiniz şey mümkün değil. GraphQL, sorgunuzdan hangi alanları döndürmek istediğinizi belirleme konusunda açık olmanızı gerektirir.


5
Tamam, ve arka uçtan proxy yapmam veya geri göndermem gereken bilinmeyen bir formda bir nesne talep edersem?
meandre

19
@meandre, graphql'in tüm fikri "bilinmeyen form" diye bir şey olmadığıdır.
s.meijer

2
@meandre, Aşağıdaki cevabım sizin için yararlı olabilir mi?
Tyrone Wilson

Çoğu API sorgu dili ve protokolü fikri bu değil mi ?, @meandre
Clijsters

ilginç, graphql kullanırken gerçekten farklı bir zihniyet
andy

91

Evet, bunu iç gözlem kullanarak yapabilirsiniz . ( UserType türü için ) gibi bir GraphQL sorgusu yapın

{
   __type(name:"UserType") {
      fields {
         name
         description
      }  
   }
}

ve şöyle bir yanıt alırsınız (gerçek alan adları, gerçek şema / tür tanımınıza bağlı olacaktır)

{
  "data": {
    "__type": {
      "fields": [
        {
          "name": "id",
          "description": ""
        },
        {
          "name": "username",
          "description": "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
        },
        {
          "name": "firstName",
          "description": ""
        },
        {
          "name": "lastName",
          "description": ""
        },
        {
         "name": "email",
          "description": ""
        },
        ( etc. etc. ...)
      ]
    }
  }
}

Daha sonra istemcinizdeki bu alanların listesini okuyabilir ve tüm bu alanları almak için ikinci bir GraphQL sorgusu dinamik olarak oluşturabilirsiniz.

Bu, alanları almak istediğiniz türün adını bilmenize bağlıdır - türü bilmiyorsanız, iç gözlem kullanarak tüm türleri ve alanları bir araya getirebilirsiniz.

{
  __schema {
    types {
      name
      fields {
        name
        description
      }
    }
  }
}

NOT: Bu, kablosuz GraphQL verileridir - gerçek istemcinizle nasıl okuyup yazacağınızı kendiniz çözersiniz. GraphQL javascript kitaplığınız zaten bazı kapasitelerde iç gözlem kullanıyor olabilir, örneğin apollo codegen komutu türleri oluşturmak için iç gözlem kullanır.


Özyinelemeli türlere özen gösterilmesi gerekiyor gibi görünüyor. Ağaçtan aşağı inip, kendisini bir biçimde içeren (liste, tek veya başka ..) bir türe çarptıysanız, sonsuz bir özyineleme içinde olabilirsiniz.
Milos Grujic

Bu belirli sorgu ile ilgili deneyimime göre aslında bu gerçekleşmiyor - sorgunun kendisi çözüm derinliğini tanımlar.
Mark Chackerian

Yukarıdaki cevap yalnızca bir sorguda bulunan alan türlerini sorgulamanıza izin verir. Tüm nesne alanlarının "değerlerini" döndürmez, bu da asıl soru ile ilgilidir.
quantdaddy

4
Cevaba göre, ilk sorgunun sonuçlarına göre dinamik olarak ikinci bir sorgu oluşturmanız gerekir - bunu okuyucu için bir alıştırma olarak bıraktım.
Mark Chackerian

39

Sanırım bunu yapmanın tek yolu yeniden kullanılabilir parçalar kullanmak:

fragment UserFragment on Users {
    id
    username
    count
} 

FetchUsers {
    users(id: "2") {
        ...UserFragment
    }
}

19
Bunu yaptıysam, yine de her alan adını "en azından parçada" yazmam gerekiyor, kaçınmaya çalıştığım şeyi cadı, GraphQL bizi açık olmaya zorluyor gibi görünüyor.
BlackSigma

bunu bir POSTMan sorgusuna nasıl ekleyebilirim? veya jquery / UI çerçevesini dizgeleştirilmiş bir JSON yapmak için. Bu graphiQL gerçek geliştirme amacı için yararsız görünüyor.
mfaisalhyder

Bu yalnızca yeniden kullanım amaçlıdır.
Henok Tesfaye

@BlackSigma GraphQL belgelerine bakıldığında , bu en iyi cevap olarak kabul edilmelidir
JP Ventura

4
@JPVentura: Hayır dostum, hem konsept hem de uygulamada yeniden kullanılabilirlik ile joker karakter arasında bir fark var. Parçanın amacı, "GraphQL, parça adı verilen yeniden kullanılabilir birimleri içerir" belgelerinde açıktır. Parça kullanmak faydalıdır, ancak sorunun cevabı değildir.
BlackSigma

11

Google places API'den veritabanına serileştirdiğim konum verilerini yüklemem gerektiğinde aynı sorunla karşılaştım. Genelde her şeyin haritalarda çalışmasını isterdim ama her seferinde tüm alanları belirtmek zorunda kalmak istemedim.

Ruby'de çalışıyordum, bu yüzden size PHP uygulamasını veremem ama prensip aynı olmalıdır.

Yalnızca birebir JSON nesnesi döndüren JSON adlı özel bir skaler tür tanımladım.

Ruby uygulaması da böyleydi (graphql-ruby kullanarak)

module Graph
  module Types
    JsonType = GraphQL::ScalarType.define do
      name "JSON"
      coerce_input -> (x) { x }
      coerce_result -> (x) { x }
    end
  end
end

Sonra onu böyle nesnelerimiz için kullandım

field :location, Types::JsonType

Bunu çok idareli bir şekilde kullanırdım, sadece her zaman tüm JSON nesnesine ihtiyaç duyduğunuzu bildiğiniz yerde kullanırdım (benim durumumda yaptığım gibi). Aksi takdirde, daha genel olarak konuşursak, GraphQL nesnesini yeniyor.


1
Bu tam olarak ihtiyacım olan şey, teşekkür ederim. Benim kullanım durumum, sistem boyunca kullanıcı tarafından çevrilebilir dizelerim var ve bunlar db gibi json olarak saklanıyor {"en": "Hello", "es": "Hola"}. Her kullanıcı kendi kullanım durumu için kendi dil alt kümesini uygulayabildiğinden, kullanıcı arayüzünün olası her alt kümeyi sorgulaması bir anlam ifade etmez. Örneğiniz mükemmel çalışıyor.
Luke Ehresman

2

GraphQL sorgu biçimi şunlara izin vermek için tasarlanmıştır:

  1. Hem sorgu hem de sonuç şekli tamamen aynıdır .
  2. Sunucu , istenen alanları tam olarak bilir , bu nedenle istemci yalnızca gerekli verileri indirir .

Bununla birlikte, GraphQL belgelerine göre , seçim setlerini daha yeniden kullanılabilir hale getirmek için parçalar oluşturabilirsiniz :

# Only most used selection properties

fragment UserDetails on User {
    id,
    username
} 

Daha sonra tüm kullanıcı ayrıntılarını şu şekilde sorgulayabilirsiniz:

FetchUsers {
    users() {
        ...UserDetails
    }
}

Parçanızın yanına ek alanlar da ekleyebilirsiniz :

FetchUserById($id: ID!) {
    users(id: $id) {
        ...UserDetails
        count
    }
}

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.