You are viewing documentation for a previous version of this software.

Switch to the latest stable version.

9. Write your first mutation


In this section, you will write your first mutation to log in to the backend. A mutation is used to change data on your server. Here the login mutation will create a session based on your email address.

Note: The way you log in to this particular server might differ from the way you log in with your own server. Login is often handled by middleware, or a layer totally separate from GraphQL, like Oauth. Also note that a typical authentication flow should require a password but for this tutorial, anyone is allowed to book flights with a valid email address!

Prototype your mutation in GraphQL Playground

Open GraphQL Playground and select the login mutation in the docs tab on the right:

The definition of login in the schema

This mutation takes a single argument, the email address of the person being logged in. Unlike many GraphQL operations that return objects which need to have fields selected, the login mutation returns only a single string.

Type the following mutation in GraphiQL:

GraphQL
1mutation Login($email: String) {
2  login(email: $email)
3}

If you hit Play, you should get a null login:

Results of not passing email

This is expected, because you didn't specify your email. To do so, add it to the Query Variables in the lower-left pane of GraphQL Playground:

JSON
1{ "email": "me@example.com" }

Press the Play button, and you'll get an actual response:

Results of passing an actual email

Add the mutation to the project

Now that your mutation is working, add it to your project. Create a file named Login.graphql next to schema.json and your other GraphQL files and paste the contents of the mutation:

GraphQL
app/src/main/graphql/com/example/rocketreserver/Login.graphql
1mutation Login($email: String) {
2  login(email: $email)
3}

Build your project to generate the LoginMutation class.

Connect the Submit button to your mutation

Open LoginFragment.kt and like you did for the other fragments, override onViewCreated. Add a click listener and some checks to verify that the email is a valid email:

Kotlin
app/src/main/java/com/example/rocketreserver/LoginFragment.kt
1    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
2        super.onViewCreated(view, savedInstanceState)
3
4        binding.submitProgressBar.visibility = View.GONE
5        binding.submit.setOnClickListener {
6            val email = binding.email.text.toString()
7            if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
8                binding.emailLayout.error = getString(R.string.invalid_email)
9                return@setOnClickListener
10            }

From the click listener, display the ProgressBar and execute the query with the email the user just entered:

Kotlin
app/src/main/java/com/example/rocketreserver/LoginFragment.kt
1            binding.submitProgressBar.visibility = View.VISIBLE
2            binding.submit.visibility = View.GONE
3            lifecycleScope.launchWhenResumed {
4                val response = try {
5                    apolloClient.mutate(LoginMutation(email = Input.fromNullable(email))).await()
6                } catch (e: Exception) {
7                    null
8                }

Handle errors if needed:

Kotlin
app/src/main/java/com/example/rocketreserver/LoginFragment.kt
1                val login = response?.data?.login
2                if (login == null || response.hasErrors()) {
3                    binding.submitProgressBar.visibility = View.GONE
4                    binding.submit.visibility = View.VISIBLE
5                    return@launchWhenResumed
6                }

Finally if everything is successful, store the login and go back to the previous screen:

Kotlin
app/src/main/java/com/example/rocketreserver/LoginFragment.kt
1                User.setToken(requireContext(), login)
2                findNavController().popBackStack()
3            }
4        }
5    }

User is a helper class that saves the token in EncryptedSharedPreference. This is the reason why this tutorial uses API level 23+. Apollo Android itself supports API levels 19+.

Test the login

Go the details fragment, click Book and in the Login fragment, enter your email and click Submit. You now have a token that allows you to authenticate your queries.

The login screen

In the next section, you will authenticate your queries.

Feedback

Edit on GitHub

Forums