Before going to the data modeling we need to create the graphQL API.
Go to the link to create the graphQL API
This may looks time consuming. But if you're new to Data Modeling give it a shot. You're basic will be far more then clear.
Before start creating schema we've to know about some directives we're going to use while creating graphQL schema. And if don't have any idea about what GraphQL is then get some basic about GraphQl
Directives
@model @auth @hasOne @hasMany @belongTo @manyToMany @searchable @primaryKey and @index ....
@model
Store objects in DynamoDB
Configure CRUD resolvers
@auth
- API authorization strategies
@hasOne, @hasMany, @manyToMany, @belongsTo
- Create relationships between @model
object types
@searchable
- Active search and sorting at the same time from database.
@primaryKey, @index
- Override default key property with custom data
Data Modeling
Now we're going to setup database tables using API(GraphQL)
Data types
- Scalar type: title, content (Contains scalar value like ID, String, Int, Float, DateTime etc.)
- Object type: Todo (which is a JavaScript Object)
Without @model
directive, we'll not get any CRUD resolvers
1. @model
By adding @model
directive we will get all the CRUD resolvers
Resolvers | Description |
---|---|
getTodo | Get one todo document using id or primaryKey
|
listTodo | Get all todo documents |
createTodo | Insert one todo document |
updateTodo | Update one todo document using id or primaryKey
|
deleteTodo | Delete one todo document using id or primaryKey
|
2. @auth
By adding @auth
directive we will get the permission to use CRUD resolvers. Otherwise we might get an error about unauthorization.
createTodo, updateTodo, deleteTodo
To create, update & delete a document in DB, we've to start the query withmutation
createTodo
- id: id is auto generated
- title: title comes from
input
objecttitle
field- content: content comes from
input
objectcontent
field
getTodo, listTodo
To get a document or all documents, the best practice is to start the query withquery
getTodo
- id: Provide id to get a document from DB.
- title, content data will come from DB
listTodos
- id: Don't need id to get data
- title, content & other propertise will come from DB
deleteTodo
- id: Provide id to delete match document
- whole document object will delete from DB
3. @index
By using secondary index or @index
directive we can create another extra queryField
- To use
todoByTitleAndRank
we've to provide title as argument in the query field - To use
todoByRank
we've to provide rank as argument in the query field
Setup relationships between models
Directive | Data flow | Relationship | Example |
---|---|---|---|
@hasOne |
One-directional | one-to-one | A project "has one" team |
@hasMany |
One-directional | one-to-many | A post "has many" comments |
@belongsTo |
Bi-directional | one-to-one or one-to-many | A project has one team or a team belongs to a project |
@ManyToMany |
Bi-directional | many-to-many | A blog has many tags and a tag has many blogs |
4. @hasOne
- One-directional : We'll get child object inside of a parent object. Below here Child object is Team and Parent object is Project
- One-to-one : We'll get only one child inside of a parent object.
createTeam
- teamName: Provide team name
createProject
- projectName: Provide project name
- projectTeamId: Provide the exact same id of Team. This default field will be created and matched with the team id field & get the team data. We can override this field.
listProjects
- Team data will be found if projectTeamId === team.id.
- We'll get team data inside of project.
- But if we try to get project data inside of team it'll give us an error.
@hasOne(fields: ["fieldName"])
- This will override the default field (projectTeamId) by fieldName (teamID). We will not find the default field again.
- Now instead of matching projectTeamId === team.id, it is matching teamID === team.id.
5. @hasMany
- One-directional : We'll get array of child objects inside of a parent object. Below here Child object is Comment and Parent object is Post
- One-to-many : We'll get one or more child inside of a parent object.
createPost
- postName: Provide post title
createComment
- commentContent: Provide comment string
- postCommentsId: Provide the exact same id of Post. This default field will be created and matched with the Post id field & get the comment data. We can override this field.
- Adding another comment
listPosts
- Comments will be found if postCommentsId === post.id
- We'll get array of comment inside of post.
- But if we try to get post data inside of comments it'll give us an error.
@hasMany(indexName: "byPost", fields: ["id"])
postID: ID! @index(name: "byPost", sortKeyFields: ["content"]
- This will override the default field (postCommentsId) by property of index (postID). We will not find the default field again.
- Adding post
- Adding comment 1
- postID: Provide the exact same id of Post. This field will override the postCommentsId field and match the Post id field & get the comment data.
- Adding comment 2
- Now instead of matching postCommentsId === post.id, it is matching postID === post.id.
6. @belongsTo
- Bi-directional : We'll get array of child objects inside of a parent object & we'll also get parent inside of. Below here Child object is Comment and Parent object is Post
- Difference
Directive | Can be found child data inside parent object | Can be found parent data inside child object |
---|---|---|
@hasOne |
Yes | No |
@hasMany |
Yes | No |
@belongsTo |
Yes | Yes |
- I'm explaining
@belongsTo
directive for@hasMany
relation. You should try out@belongsTo
directive for@hasOne
relation. There is no change in creating@hasOne
and@hasMany
schema and data table.Just we will find parent data inside of a child object.
createPost
- Provide postName
createComment
- Creating relation between two table by postCommentsId
- Add comment 2
listPost
- Getting child (comments) data inside parent (post) object
- Getting parent (post) data inside child (comments) object
@hasMany(indexName: "byPost", fields: ["id"])
postID: ID! @index(name: "byPost")
- This will override the default field (postCommentsId) by property of index (postID). We will not find the default field again.
createPost
- Provide postName
createComment
- postID: Provide the exact same id of Post. This field will override the postCommentsId field and match the Post id field & get the comment data.
- Adding comment 2
listPost
- Getting child (comments) data inside parent (post) object
- Getting parent (post) data inside child (comments) object
7. @manyToMany
- This relation will create 3 data table.
Table | get | list | create | update | delete | subscription | Found Data Object |
---|---|---|---|---|---|---|---|
Post |
Yes | Yes | Yes | Yes | Yes | Yes | Post, Tag, PostTags |
Tag |
Yes | Yes | Yes | Yes | Yes | Yes | Post, Tag, PostTags |
PostTags |
Yes | Yes | Yes | Yes | Yes | Yes | Post, Tag, PostTags |
- Bi-directional : We'll get one table inside of another table.
createPost
- postName: Provide post name to create a post.
create Tag
- label: Provide label title to create a tag label.
createPostTags
postID: Use to provide post object.
tagID: Use to provide tag object.
Advanced
Create multiple relationships between multiple model
- Department has one manager and many employees
- Manager has one department and many employees
- Employees has one department and one manager
createDepartment
- Provide Department name in the departmentName input
- We don't have manager and employee id. So we'll update the department later.
createManager
- Provide manager name in the managerName input
- Provide department id in the departmentID input.
createEmployee
- Provide employee name in the employeeName input
- Provide department id in the departmentID input.
- Provide manager id in the managerID input.
- And we're getting department and manager info in the Employee table
updateDepartment
- Provide selected department id in the id input
- Provide manager id in the managerID input
- and we're getting employee and manager info in department table.
listManagers
- And we're getting department and employee info in manager table.
That's it for now. Thanks for your patience. If this blog help you please give a react.
Next blog will be about filtering...
Top comments (5)
Waiting for next one 🤗
Thank you so much, this article is very helpful.
Welcome
Thanks,
I have a question, how to delete relations? ex. a Post has many tags, what if I want to remove a tag from a post?
1st scenario:
If you want to remove a tag from posts you have to do deleteTag mutations.
deleteTag and give the tag id. That tag will remove from all the posts it's linked to.
2nd scenario:
If you want to delete a tag from a particular post you have to do updatePost mutations.
updatePost and provide the post id, then pass an empty string in the field where you provided the tag id to link post and tag.