Open atherdon opened 6 years ago
Okay, working on it! :)
As you more familiar with our github workflow, please start reading first chapters asap and put here your progress. I think this will motivate our other team members to start a race. just a little competition does not harm, right? let's this will be our secret :)
Please add me as a collaborator to this one @atherdon. For now I have forked this repo.
@atherdon Okay so last night I learnt a lot about GraphQL, how it differs from the conventional RESTful APIs and some basic concepts of GraphQL. Basically it provides a single end-point
which have ability to handle resource, contrary to REST which just hands over data from the resource and has multiple end-points. To use GraphQL, we need to define a Schema
first, which is the raw structure in which data is stored. We also need a resolver function
to maybe tell GraphQL how to fetch data, but that is not very clear with my current understanding.
I have added a file server.js and was able to run in on command line by doing node server.js
.
For setting the project up, I used this [https://graphql.org/graphql-js/]
please follow this link: https://github.com/GroceriStar/playing-with-graphql/invitations
Please hold on with an actual coding part. I mean at first i want to understand that you know main features and basics.
then we'll build some sort of pseudo-code
in graphql schemas in order to practice it and discuss database improvements. main feature in GraphQL that you can easily extend the database - this is what hold my project back with REST API approach.
we have at least few databases and i prepare some plan so we actually will not just replicate logic of our current API servers, but we also will extend and update it. Some details please read here: https://medium.com/groceristar/chickenkyiv-database-logic-intro-part-1-b2c449d92aa3 https://medium.com/groceristar/chickenkyiv-database-logic-simple-samples-part-2-1ee3ccc6b3d https://medium.com/groceristar/chicken-kyiv-recipe-db-schema-part3-b80f33ec5d96
@atherdon Thanks for providing me some perspective over the project, and yes I too realized that getting the basics of this is important. Specially for me because I have not worked much with APIs or back-end.
i adore your pro-activity - don't want to loose it. But let's strict to main plan. this will be also more easy for me to follow your progress. So please check description of this task again - and try to explain to me for each sections at graph-ql intro what do you learn. this will raise a discussion between you and me, and we'll be able to start actual work at graphQl schema. when it'll looks cool - we'll start to test it.
Because actually - we have everything for it. We have a mongodb, we have imported data to it. so only schemas holding us back.
Btw, can you move that links to readme(please separate them from trash links that i store there), so other developers will have access to them too
"url": "mongodb://heroku_p3w65n77:h3ab8q3uaqdk7tjrauhbl7dd6r@ds235065.mlab.com:35065/heroku_p3w65n77",
"name": "groceryDS",
"searchDS": { "url": "mongodb://heroku_ghbnqks1:eb8kogbcofqvkh13d6ccep825l@ds139994.mlab.com:39994/heroku_ghbnqks1",
"recipeDS": {
"url": "mongodb://heroku_p0dxgncb:gl2rr2bi235aoqfdojelqspjn1@ds147052.mlab.com:47052/heroku_p0dxgncb",
This is links to our mongo databases - please move them to readme too
This chapter talks about how GraphQL service is created. Basically we first define types and then fields on those types. Also the datatype on each field is specified here. We also provide functions for each field on each type so that we can retrieve that data(, or do something with it). It also describes how to send a query to receive data, which is very simple and flexible way to do so.
which chapter?
please follow this template:
"This chapter talks about how GraphQL service is created. Basically we first define types and then fields on those types. Also the datatype on each field is specified here. We also provide functions for each field on each type so that we can retrieve that data(, or do something with it). It also describes how to send a query to receive data, which is very simple and flexible way to do so."
brackets{ }
and specify the required fields....fragmentName
.mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) { createReview(episode: $ep, review: $review) { stars commentary } }
Shouldn't it be something like:
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) { createReview(episode: $ep, review: $review) { review { stars commentary } } }
Anyways I think things will get clear as I move on with it.__typename
can be used to determine to the type of the returned data, which can then be used to select what we want from the data.@sanchit94 perfect!
please move this links to readme too: we have at least few databases and i prepare some plan so we actually will not just replicate logic of our current API servers, but we also will extend and update it. Some details please read here: https://medium.com/groceristar/chickenkyiv-database-logic-intro-part-1-b2c449d92aa3 https://medium.com/groceristar/chickenkyiv-database-logic-simple-samples-part-2-1ee3ccc6b3d https://medium.com/groceristar/chicken-kyiv-recipe-db-schema-part3-b80f33ec5d96
I think you saw this schemes, but i'll put it here, please move them to our readme too https://chickenkyiv.gitbook.io/documentation/database-schemes
https://github.com/ChickenKyiv/database-visuals
https://github.com/ChickenKyiv/database-visuals/tree/master/groceristar/models https://github.com/ChickenKyiv/database-visuals/tree/master/rapi/models https://github.com/ChickenKyiv/database-visuals/tree/master/recipeSearchAPI/models
Done! 👍
field
of the object
in the schema definition. Types can be defined as in Object types
using the type
keyword, or they can be built-in scalar types
. By this, we can have an idea of what to expect when a query
is made. Types are also needed for validation of the query.SDL(Schema Description Language)
for describing schema
of the GraphQL service.fields
inside it, where each field can have a scalar type
as it's type or another object type
as it's type. Basically this is the way of implementing relational databases.multiple
arguments``, but they need to be explicitly passed by name. If an argument is optional we can assign a default value to it.query type
which defines the entry-point for the GraphQL query. It may or may not have a mutation type
. Defined using type
keyword. Question: Can I only query data of fields for which I have a query type?leaves
of the query, the fields that have these types do not have a sub-field. GraphQL has following scalar types: Int, String, Float, Boolean, ID.
We can also specify custom scalar types, using scalar
keyword by doing scalar typeName
enum
keyword to define an 'enum'.type modifiers
to extend our type. We can do String!
to make the string type non-nullable
. Once !
is added to the type, the server always expects a non-null value from that field. Second type modifier is List
, where we can mark a field to return a list(kind of array) of values by wrapping [ ]
around the type name.
Both type modifiers can be flexibly combined according to need. Like we can do Numbers : [Int!]
to indicate the Numbers field is a list of Int
values, where each entry in the list is a non-null object. Although the list can be null itself. Numbers: [Int]!
means the list is non-null, but a member of a list can be null. Numbers : [Int!]!
means neither the list nor any member on the list is null.in-line fragment
.union Breakfast = Sandwiches | Omelet | Oats
means that the union type Breakfast
can be either of the types Sandwiches, Omelet or Oats
. When querying union types, we should always use in-line fragments
for each type(Sandwiches, Omelet, Oats) so that there is no error.input
keyword. Then we can start passing them. Useful for mutations
, where we pass these input types to the object, we can even pass them as variables
. Pretty cool! :)Validation is done using type system to determine whether a query is valid or not. So there are some rules that we need to follow. There are a few rules that are mentioned in the documentation:
fragment
cannot refer to itself: As this would create a cycle, sort of recurrence
but there is no exit from it. So doing this will lead to an invalid query.
For e.g.
food {
...details
sameCuisine {
...details
sameCuisine {
...details
}
}
}
fragment details on foodItems { name cuisine }
This valid query, but if we try to implement the same using a fragment like
fragment details on foodItems { name cuisine ...details }
then it is invalid, as a fragment is calling itself.
2. When querying `fields`, only query for `fields` that are present in that `type`: Self explanatory, if we search for a field that is not present in the type, then it will be an error.
3. If the query returns something other than a `scalar `or `enum`, like an object type, then we need to specify which `fields` we want from that object. If we fail to do so the query is **invalid**. Question: What is the best practice in cases we need info of all fields? Do we make an enum?
4. If a field is `scalar`, we cannot query any fields inside it.
5. If our type `implements` an `interface`, then we can directly query only the fields on the `interface`. For querying **type-specific fields**, we can either use `inline fragments` or create a `fragment` on the type.
GraphQL query is executed after Validation which resolves to a JSON response, generally.
Each field in a query has a corresponding resolver method
which is a function that tells the service how to handle the query. This means it returns the type that is expected, and if that type is a scalar
type, it would return the value. This completes the execution. A query always ends at the scalar type.
Root fields and resolver: Root type is the top level of the query. In the example given in the documentation, the root query has a resolver function human, which takes four arguments:
obj
: The previous object, which we have to enter in order to resolve the query. This is not need for root resolver function.args
: The argument provided, for e.g. id
, or name
.context
: Haven't got much idea what this is, but I think we will get to know more about the details of this as we move along. Maybe it contains methods to fetch data, like getHumantById.info
: Containing field specific information and schema details.Asynchronous Resolvers: The query does not always return data, but it returns a Promise
, which can be passed around as a token even if we do not have the value yet, in hope that when the Promise is fulfilled
, it will provide the data. During execution GraphQL waits for the Promises to resolve(or be rejected).
Trivial Resolvers: Trivial resolver is one that simply fetched the value of the field. Some libraries let us omit these trivial resolvers and do this for us by default.
Scalar Coercion: GraphQL can use scalars
(or numbers) internally to store values of some objects. Once the query is made, the scalar is returned and the corresponding value to this scalar that is mapped can be returned.
List Resolvers: When a field type is a list, then GraphQL will return a list of Promises
on that.
Producing the result: As the fields are resolved, the result is displayed in form of key-value pair(JSON) which looks like the query we requested.
btw, we're continue our work on grapqhql server, maybe this will be also interesting for you as backend development. repo: https://github.com/GroceriStar/graphql-server
Please start by reading the documentation, related to GraphQL: https://www.howtographql.com/ After reading each chapter - please briefly explain to me here what did you learn from it. Format(example):
Chapter 1: Intro (https://graphql.org/learn/)
"It's covering the basics of graphql" Questions: "How i can run it at my local PC"?
@sanchit94 - it's your task