The project is here: github.com/codewithkai…
You can order this address online experience: w4u0q sse. Codesandbox. IO/(some kind of don’t automatically dormancy, open the need to wait for initialization, encounters an error, please refresh)
Consider the following example: Query a question, query the answer to the question, and the author of the answer
{
question(id: "357653771") {
title
answers {
excerpt
voteupCount
commentCount
author {
name
}
}
}
}
Copy the code
Let’s start with the background of the project. I want to teach a course on Apollo full stack development, and the example project Apollo officials gave was the SpaceX example. I didn’t want to reinvent the wheel, but I found it challenging to get a lot of domestic programmers to adapt to these examples.
After research, I found that developers like practical courses and like to copy popular Internet applications, such as Zhihu, netease Cloud Music, Ele. me, Mi Mall, etc. So I got a taste of Zhihu’s fame. My example was changed according to the official example of Apollo, but the content was changed into Zhihu.
Since Zhihu has no public API, I can only observe a little bit in Chrome development tools and then write down the API calls little by little. I’ve made a lot of discoveries along the way.
First, zhihu’s API is REST, but it already works like GraphQL. Such as the following:
-
Use the include parameter limit returned to the field of https://www.zhihu.com/api/v4/members/c7e4de899635e9ce839d90d64f0b9602?include=answer_count, follower_co unt,articles_count
-
Support some degree of nested query, such as the popular discussion list of a topic, in addition to return the answer list, the corresponding question, the author of the answer and other new information are returned together, such as: https://www.zhihu.com/api/v4/topics/20031262/feeds/top_activity?include=data[?(target.type=topic_sticky_module)].target .data[?(target.type=answer)].target.content,relationship.is_authorized,is_author,voting,is_thanked,is_nothelp; data[?(target.type=topic_sticky_module)].target.data[?(target.type=answer)].target.is_normal,comment_count,voteup_count, content,relevant_info,excerpt.author.badge[?(type=best_answerer)].topics; data[?(target.type=topic_sticky_module)].target.data[?(target.type=article)].target.content,voteup_count,comment_count,v oting,author.badge[?(type=best_answerer)].topics; data[?(target.type=topic_sticky_module)].target.data[?(target.type=people)].target.answer_count,articles_count,gender,fo llower_count,is_followed,is_following,badge[?(type=best_answerer)].topics; data[?(target.type=answer)].target.annotation_detail,content,hermes_label,is_labeled,relationship.is_authorized,is_autho r,voting,is_thanked,is_nothelp; data[?(target.type=answer)].target.author.badge[?(type=best_answerer)].topics; data[?(target.type=article)].target.annotation_detail,content,hermes_label,is_labeled,author.badge[?(type=best_answerer) ].topics; data[?(target.type=question)].target.annotation_detail,comment_count;
-
If you look closely at the URL above, data[?(target.type=question)] even contains Inline fragments like the one in GraphQL that use __typename to determine a specific type and then query the field for that specific type
-
Objects in REST have no type, but the Zhihu API uses the type field to indicate the type of the object returned. Under a topic, the essence discussion list returns, even a bit like the Interface in GraphQL
Looking at this, we might be thinking, with REST’s pain points out of the way, why bother with GraphQL?
I think of the following two things:
-
The developer experience on the front end can be very different. Include filters simple fields in an acceptable way, but expressing nested queries with include looks like a disaster. I guess the front-end development of Zhihu will not directly write such a big pile of things, but have a specially packaged client? This makes it easier for the front end to express nested relationships, resulting in such a complex URL. The writing experience is very different with GraphQL, and even more so with a Client like Apollo Client. See my video on Site B: What’s it like to develop with GraphQL on the front end? _ bi li bi li (゜ ゜ つ ロ cheers ~ – bilibili
-
In order to handle include and more complex writing methods such as data[?(target.type=question)], the back end of Zhihu also needs to do some work like the back end of GraphQL to parse query requests, determine execution schemes, and finally get and assemble data from data sources. Which layer is this work done? Maybe not as sophisticated as the GraphQL implementation, but kind of like GraphQL, right?
Of course, this is just imagination, because I have never worked in a large company, so I have no idea about the architecture of such a big application as Zhihu, and what the development experience of the front and back end is like.
Of course, from a practical point of view, zhihu’s transformation of API into GraphQL may bring relatively small benefits, while costs and problems may be relatively large. But maybe not.
In addition, to address the limitations of changing REST to GraphQL in my example: Even though Apollo says you can use REST as a data source, the actual use of REST is very performance problematic. For example, if you have 10 answers to a question and then query the author of those 10 answers, the back end actually generates 11 REST requests. Unless the REST interface of the query author supports batch queries based on multiple ids, you can combine 10 into one using Dataloader mode. Thus, the so-called N+1 problem is pushed to the server without actually solving the problem.
In fact, Zhihu’s API is not standard RESTful, but designed according to business scenarios, and it already supports nested queries. In order to demonstrate GraphQL, I threw away associated data, leaving only ID, and then used resolver to obtain this type of data separately, so it would be inefficient. If the underlying data source is a database, the demo is clearer and performance is better.
Finally, I want to write a class imitating zhihu’s RESTAPI, so I have to get familiar with zhihu’s business. From the perspective of onlookers, the complexity of zhihu is beyond my imagination, and even daunting. If I want to make a course imitating Zhihu, I’m afraid I can only imitate the most superficial things, and there are many problems beyond my understanding:
- As a social network, Zhihu faces the same problems as Facebook. How are social relationships stored and extracted?
- How do you rank the answers in the questions and the discussions under the topics?
- What about personalized recommendation content, personalized invitation answers and so on?
- How are notifications pushed?
And if you’re interested, you can visit my video course website, just starting: codeWithKai.com
For more Web development techniques such as GraphQL, follow my official account: