Por que um artigo
Recentemente, tive a necessidade de implementar o trabalho com um back-end no GraphQL. Não há muitos tutoriais para configuração no Android, ao contrário do REST, e a maioria deles não é mais relevante.O que é o GraphQL
O GraphQL é uma alternativa elegante à API REST, que permite consultar dados de uma maneira mais otimizada, fornecendo apenas os dados necessários.Configuração do ambiente
Faremos solicitações ao servidor por meio do Apollo - a biblioteca mais popular para trabalhar com o GraphQL no momento.Vamos ao trabalho. Primeiro, vamos adicionar as permissões necessárias para trabalhar com a rede no manifesto:<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Em seguida, você precisa conectar o Apollo. Vamos para o build.gradle principal e, na seção de dependências, adicionamos a seguinte linha:classpath 'com.apollographql.apollo:apollo-gradle-plugin:2.0.0'
Agora você precisa adicionar dependências adicionais no arquivo build.gradle do módulo de aplicativo:implementation("com.apollographql.apollo:apollo-runtime:2.0.0")
implementation "com.apollographql.apollo:apollo-android-support:2.0.0"
Além disso, adicione a conexão do plug-in na parte superior do arquivo:apply plugin: 'com.apollographql.apollo'
Após a sincronização do projeto, precisamos configurar a geração de código dos modelos com os quais faremos consultas ao GraphQL.Vamos minimizar o ambiente de desenvolvimento e abrir um terminal. Vá para a pasta com seu projeto:cd /Users/user/Desktop/ProjectName
Se você ainda não possui o npm, primeiro faça o download no site oficialInstale o apollo-codegen - uma ferramenta que permite baixar o schema.json - um arquivo que servirá como fonte do apollo para gerar modelos:npm install apollo-codegen
Faça o download do schema.json (você deve estar no diretório do seu projeto, onde a pasta node_modules apareceu):node_modules/.bin/apollo-codegen download-schema https:// api/ --output schema.json
Agora, na pasta do projeto, vemos o arquivo schema.json. Resta mostrar arquivos apollo para gerar modelos. Para fazer isso, execute as seguintes etapas.Vá para a pasta do aplicativo do seu projeto e, em seguida, src -> main. Aqui precisamos criar uma pasta graphQL. Aqui vamos adicionar nossos arquivos .graphql.Copie o arquivo baixado na etapa anterior para a pasta criada - schema.jsonO ambiente está configurado , vá para o códigoGeração de código do modelo
Vamos começar com os arquivos .graphql. Os pedidos serão armazenados aqui.O GraphQL possui dois tipos de consultas:consulta - um análogo damutação GET - um análogo de POST / PUT / DELETESuponha que você esteja prestando um serviço para fazer check-in de hóspedes em um quarto de um hotel para administradores deste hotel. O aplicativo pode fazer 3 funções. Faça login no usuário (administrador), obtenha informações da sala por ID e preencha convidadosCrie um arquivo loginUser.graphql no diretório app / src / main / graphQL criado na seção anterior. Usando este arquivo, o apollo irá gerar um modelo para o nome de usuário.Conteúdo do arquivo:mutation loginUser($email:String!, $password:String!) {
login(
user: {
email: $email,
password: $password
}
){
email,
token,
refreshToken
}
}
Além disso, precisamos do arquivo getRoom.graphql, com a ajuda de um modelo para gerar o quarto de hotel:query getRoom($room_id: String) {
room(room_id: $room_id) {
title,
room_number,
cheked_in_family_name,
has_minibar
}
}
E o arquivo final é checkUserIn.graphql. Também usa mutação:mutation checkInFamily($room_id: String!, $family_name: String!) {
room(
room: {
title: $family_name,
room_id: $room_id
}
){
room_id,
family_name,
minibar_products{
title,
weight
}
}
}
Criamos o projeto e vemos 3 modelos gerados na pasta app / build / generate / source / apollo / debug / service: GetRoomQuery, CheckUserInMutation, LoginUserMutationExecução de consulta
Crie uma classe NetworkService singleton que nos fornecerá o ApolloClient. Nós fazemos 2 métodos nele. getApolloClient () para executar solicitações que não exigem um token ou parâmetros adicionais e getApolloClientWithTokenInterceptor (), no qual lançaremos o token, para solicitações:import com.apollographql.apollo.ApolloClient
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
class NetworkService {
fun getApolloClient(): ApolloClient {
val okHttp = OkHttpClient
.Builder()
.build()
return ApolloClient.builder()
.serverUrl(BASE_URL)
.okHttpClient(okHttp)
.build()
}
fun getApolloClientWithTokenInterceptor(token: String): ApolloClient {
val httpClient = OkHttpClient.Builder()
.addInterceptor(Interceptor { chain: Interceptor.Chain ->
val original: Request = chain.request()
val builder: Request.Builder = original
.newBuilder()
.method(original.method, original.body)
builder.header("Authorization", "Bearer $token")
return@Interceptor chain.proceed(builder.build())
})
.build()
return ApolloClient.builder()
.serverUrl(BASE_URL)
.okHttpClient(httpClient)
.build()
}
companion object {
private var mInstance: NetworkService? = null
fun getInstance(): NetworkService? {
if (mInstance == null) {
mInstance = NetworkService()
}
return mInstance
}
}
}
Agora vamos para nossa atividade ou fragmento, aqui implementamos a execução de solicitações. Para começar, faça o login: private fun loginUser() {
val client = NetworkService.getInstance()?.getApolloClient()
val loginMutation = LoginUserMutation
.builder()
.email(emailEdit.text.toString())
.password(passwordEdit.text.toString())
.build()
client
?.mutate(loginMutation)
?.enqueue(object : ApolloCall.Callback<LoginUserMutation.Data>() {
override fun onResponse(response: Response<LoginUserMutation.Data>) {
if (!response.hasErrors()) {
val token = response.data?.login()?.token()
val email = response.data?.login()?.email()
runOnUiThread {
}
}
}
override fun onFailure(e: ApolloException) {}
})
}
Este é um exemplo de trabalho com mutação. Executamos essa solicitação sem um token no cabeçalho. Agora, vejamos um exemplo de trabalho com consulta, tente obter informações sobre a sala. Suponha que uma sala nos seja dada apenas com um token. Executamos a solicitação da seguinte maneira: private fun getRoom() {
val token = "123456"
val client = NetworkService.getInstance()
?.getApolloClientWithTokenIntercetor(token)
val roomId = "123"
val allRoomsQuery = GetRoomQuery(Input.fromNullable(roomId))
client
?.query(allRoomsQuery)
?.enqueue(object : ApolloCall.Callback<GetRoomQuery.Data>() {
override fun onResponse(response: Response<GetRoomQuery.Data>) {
if (!response.hasErrors()) {
val familyName = response.data?.room()?.family_name()
}
}
override fun onFailure(e: ApolloException) {}
})
}
Como lição de casa, tente escrever uma implementação para acomodar convidados.Links úteis:documentação do apollo-client para Android
Github apollo-client android