Açıklaması şöyle
In REST API, we fetch data from specific endpoints. Each endpoint has a particular structure. In other words, the client needs to adhere to the API structure. Basically, the request URL determines the query parameters in a REST API.However, GraphQL has a considerably different approach. Instead of multiple endpoints, a GraphQL server typically exposes only one endpoint. The structure of the response is not fixed. Instead, it is quite flexible. Basically, the client specifies what data is required and the server responds with the required data.
Root veya Hiyerarşik Sorgular
Nesneler başka nesneleri de içerebilir. Elimizde şöyle bir schema olsun
type Author { name: String! country: Int! books: [Book!]! } type Book { title: String! publishYear: Int! author: Author! }
Sadece kök nesneyi istiyorsak sorgu olarak şöyle yaparız. Burada kitapların sadece title alanını istiyoruz
{ allBooks { title } }
Cevap olarak şunu alırız
{ "allBooks": [ { "title": "Eye of the World" }, { "title": "The Way of Kings" }, { "title": "The Mistborn" } ] }
Eğer kök nesnenin diğer alanlarını da istiyorsak sorgu olarak şöyle yaparız. Burada kitapların title ve publishYear alanlarını istiyoruz
{ allBooks { title publishYear } }
Hiyerarşik sorgu için şöyle yaparız. Burada yazarların name alanını ve yazdıkları kitapların title alanını istiyoruz.
{ allAuthors { name books { title } } }
Bazı Örnekler
Örnek - parametreli
name + email çekmek için şöyle yaparız.
{"query": "query($id: String!){ retrieveUser (id: $id) {name email} }","parameters": {"id": 1}}
Sadece email çekmek için şöyle yaparız.
{"query": "query($id: String!){ retrieveUser (id: $id) {email} }","parameters": {"id": 1}}
Örnek - parametreli
Şöyle yaparız
query order($id: ID!){order(id: $id) {quantitypriceorderDate {day,month,year}isConfirmed}}
Örnek - parametreli
Şöyle yaparız
void getPostById(WebClient client, String id) {client.post("/graphql").sendJson(Map.of("query","query post($id:String!){ postById(postId:$id){ id title content author{ name } comments{ content createdAt} createdAt}}","variables", Map.of("id", id))).onSuccess(data -> log.info("data of postByID: {}", data.bodyAsString())).onFailure(e -> log.error("error: {}", e));}
Örnek - sabit parametre
Şöyle yaparız
query {recentPosts(count: 10, offset: 0) {idtitlecategoryauthor {idnamethumbnail}}}
Şöyle yaparız
Çıktı olarak şunu alırız{"data": {"User": {"name": "Fernando Doglio","posts": [{"title": "Post #1","post_date": "2021-06-28"}...],"followers": [{ "name": "Follower #1" },{ "name": "Follower #2" }]}}}
{"data": {"User": {"name": "Fernando Doglio","posts": [{"title": "Post #1","post_date": "2021-06-28"}...],"followers": [{ "name": "Follower #1" },{ "name": "Follower #2" }]}}}
Örnek - DataLoader
Şöyle yaparız. Bir tane viewer nesnesi döner.
Açıklaması şöylequery CompanyData {viewer { # DataLoader called usersByIdcompany(id: "1") { # DataLoader called companiesByIdnametransports { # DataLoader called transportsByCompanyIdnumbercarrier { # Dataloader called companiesByIdname}}}}}
Assuming, for example, that the user has access to 5 transports. Without DataLoaders, we would be looking at 8 database queries:1 call to fetch the user (viewer)1 call to fetch company with ID 11 call to fetch the 5 transports5 calls to fetch the carriers for each of the transportsIn this example, the benefit comes from the companiesById DataLoader, as it groups the 5 calls for getting the carriers of the transports into a single database query, therefore, saving us from making 4 database queries.You can imagine scaling this example to something more plausible, such as the user having access to 500 transports, with DataLoaders, the database query count is still 4, without DataLoaders, it would now be 503.This approach helps us solve the aforementioned N+1 problem, whilst maintaining privacy by sandboxing each request to a separate set of DataLoaders — the cached results are not shared between requests, meaning any permissions logic is never shared.The DataLoaders also avoid errors in database queries by avoiding duplication of database queries, as well as speeding up the developer experience. More often than not, there already exists a DataLoader for the entity that the code is working with.
Hiç yorum yok:
Yorum Gönder