jonathasmarques04 / instaQChallenge

0 stars 0 forks source link

[Track 4/9] Create user mutation #9

Open taki-tiler-server[bot] opened 1 month ago

taki-tiler-server[bot] commented 1 month ago

Step 1/4 - The mutation setup

Estimated time: 1 hour

On this track, you're going to develop a mutation to create users on database. Let's start with baby steps, by creating the mutation prototype, with no integration to the dabatase (yet). The main purpose of this step is to exercise only how to create a mutation, a type and an input type on GraphQL Schema.

Let's call the mutation createUser. It will receive an object of the type UserInput, which you can call data, with the following fields:

{
  "data": {
    "name": "User Name",
    "email": "User e-mail",
    "password": "user password",
    "birthDate": "01-01-1990"
  } 
}

The response will be a type that is very alike to the input (you can call it User) with the addition of an id field. This will be the primary key of the User table on database. Also, we shouldn't return password field 🔑, but the GraphQL Schema should get it covered for us. Thanks, GraphQL!

Tip: make sure to create the resolver, which is the code that will be executed and the schema, which is the type definition of the GraphQL queries/mutations and input/types.

For now, you can just return the input that was given, adding an id with any number mocked.

{
  "data": {
    "createUser": {
      "id": 1,
      "name": "User Name",
      "email": "User e-mail",
      "birthDate": "01-01-1990"
    }
  } 
}

Note: Did you notice that there is a data object wrapping the createUser response? Don't worry, it's the GraphQL response format. It wraps all the successful response inside the data object and all the errors in an errors array of objects. You can read more about it here.

Note 2: don't forget to open Pull Requests at the end of every step that has some code to be written!

jonathasmarques04 commented 1 month ago

finish

taki-tiler-server[bot] commented 1 month ago

Step 2/4 - Integrate with the database

Estimated time: 2 hours

After creating the mutation prototype, it's time to integrate it with the database. For the given input, create a new user entity and save it on database. Then, return created user. Note that you can set the ORM to create the primary key automatically, meaning you can return the user with its id already created.

You can check on TablePlus (or DBeaver, if you are on a Linux machine, or the other software of your choice) if the user was properly created on database.

NOTE: any operation on database is an async task. This means that you should finish the mutation and return only when you're sure that the user was created on database. If you're not comfortable with the concept of Promises, we suggest you take some time to read about it.

jonathasmarques04 commented 1 month ago

finish

taki-tiler-server[bot] commented 1 month ago

Step 3/4 - Input validation

Estimated time: 1 hour

Validating the input is an important part of the job. We have to make sure that the client is sending valid data to be stored, or we could end up having many inconsistencies on database.

  1. The system should not allow a weak password. That being said, a valid password should have:

    • At least 6 characters
    • At least 1 letter and 1 digit
  2. The system should not allow two or more users with the same e-mail

You can add some more validations if you want, like minimum and maximum birth date. But the most important are those two above, and for the onboard, it's enough.

Since we're using GraphQL, any error thrown on a resolver returns a response with the errors field filled. We will have a step later on to discuss about proper "error handling". For now, if any validation doesn't check, you can just throw a generic error with a message.

jonathasmarques04 commented 1 month ago

finish

taki-tiler-server[bot] commented 1 month ago

Step 4/4 - Storing the password

Estimated time: 2 hours

One of the required fields to create a user is the password. You should have read or heard already that storing users password as plain text in the database is a bad idea. If not, you're reading now: it is a bad idea 🤦‍. The minimum security we should have on this case is to use a hash algorithm to store the password. This is not a 100% secure method, but it helps already.

Change your createUser mutation to store the password with a hash algorithm of your choice.

NOTE: Want to know more about how to store passwords securely? Check this post for additional details. Since this is only an onboard server, you don't need to have an ultra-master-blaster security method. Our main goal here is to show you some levels of security and prevent you from making those basic security mistakes (like storing the plain-text password, for example).

jonathasmarques04 commented 1 month ago

finish

taki-tiler-server[bot] commented 1 month ago

Click here for your next track