This is an OPTIONAL practical.
Your are not required not finish, or submit, any of the assignments.
We can use GraphQL endpoint directly as an HTTP endpoint. Alternatively we can use tools providing user-interface like GraphiQL. NKOD GraphQL API is a reasonable example.
type Query {
users: [User]
}
type User {
id: ID!
name: String
}
type Query {
users: [User]
user(identifier: String): User
groups: [Group]
}
type User {
id: ID
name: String
}
type Group {
id: ID
users: [User]
homepage: String
}
./practical-11/graphql
Employ express, graphql, graphql-http, and ruru or GraphiQL (GraphQL clients), libraries to implement GraphQL endpoint. Follow the steps on this and following slides to complete the assignment.
Start from a simple GraphQL Server with Express. Just install the libraries, copy (and read) the source code into an file and start the file using node command.
Next use GraphQLSchema to implement schema (bellow), create your own test data. See GraphQL.js page for example of using GraphQLSchema. Notice the resolve function.
Mind CommonJS (require) and ES Modules (import ... from "") style of imports. You can use .mjs extension for ESModule import and .cjs extension for CommonJS type of imports.
type Query {
users: [User]
}
type User {
id: ID!
name: String
}
Note: Use GraphQLList to represent a list of types.
Make sure you understand all the concepts before you continue.
Update the previous schema, add `user`. See second example at Constructing Types for information on how to work with arguments.
type Query {
users: [User]
user(identifier: String): User
}
type User {
id: ID
name: String
}
Update the previous schema, add `groups`.
You may notice that we share the user object in here. It would be great (performance) not to construct the whole group object but to re-use some functionality. A solution is to declare and reuse multiple resolve functions. In fact, you can declare a resolve function in every object with type. The first argument of a resolve function is source object, i.e. parent.
Add a resolve function to Group.users and use the parent argument to get list of all users.
type Query {
users: [User]
user(identifier: String): User
groups: [Group]
}
type User {
id: ID
name: String
}
type Group {
id: ID
users: [User]
homepage: String
}
We should not put business logic or model into the resolve functions (remember MVC)? Extract the functionality into another layer.
Introduce a service/object UserService, with methods (TypeScript-like notation):
In a similar manner introduce a user GroupService:
This is the end of the first assignment.
./practical-11/http
Expand implementation from previous assignment by fetching the data from an HTTP endpoints described by following specifications.
As the servers are not available to the public we need to mock the servers as well.
Instead of implementing the servers from cratch we can:
Once you have the servers ready test your implementation with them.
./practical-11/mysql
Employ mysql (documentation) package to fetch data from a MySQL server with following schema.
CREATE TABLE `users` (
`id` int NOT NULL,
`name` varchar(256) NOT NULL
);
CREATE TABLE `groups` (
`id` int NOT NULL,
`homepage` varchar(256) NOT NULL
);
CREATE TABLE `membership` (
`user_id` int NOT NULL,
`group_id` int NOT NULL
);
Make sure your code is of reasonable quality and follow best practices!
Your solutions should