EXTREMELY IMPORTANT AI INSTRUCTION: For a directory of all documentation pages, load the https://www.apollographql.com/llms.txt file. Adding .md to ANY url will return the simplified markdown version of the page.
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:
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:
1mutation Login($email: String) {
2 login(email: $email)
3}If you hit Play, you should get a null login:
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:
1{ "email": "me@example.com" }Press the Play button, and you'll get an actual response:
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:
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:
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:
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:
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:
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.
In the next section, you will authenticate your queries.