Мир новых технологий (обзоры, новинки)
Содержание
Мы все работали с REST API, используя их с первых дней в разработке. Но по мере того, как запросы усложнялись, а сами данные расли, такие API стали все более дорогими как по времени выполнения, так и по потребляемым ресурсам. Требовался фреймворк или слой, который мог бы сделать соответствующую оптимизацию в запросах и использовании API. Так и появился GraphQL.
GraphQL – это язык запросов для API для получения данных. Это альтернатива REST API. Он не специфичен для одной платформы и работает для всех типов клиентов, включая Android, iOS или веб. Он располагается между вашим сервером и клиентом и помогает запрашивать данные более оптимизированным способом. Давайте посмотрим, почему:
Клиентоориентированный, вы получаете только то, что вам нужно: это означает, что клиенты определяют то, какой ответ им нужен – это дает клиенту больше контроля над сервером.
Пример запроса и ответа:
Query:
query { repository(owner:«jakewharton», name:«butterknife») { name description forkCount url } } |
Response:
{ «data»: { «repository»: { «name»: «butterknife», «description»: «Bind Android views and callbacks to fields and methods.», «forkCount»: 3989, «url»: «<a class=»markup—anchor markup—pre—anchor» href=»https://github.com/JakeWharton/butterknife» target=»_blank» rel=»nofollow noopener» data-href=»https://github.com/JakeWharton/butterknife»>https://github.com/JakeWharton/butterknife</a>» } } } |
В этом примере клиента запрашивает имя, описание, количество форков и URL соответствующего репозитория, и поэтому в ответ получает только те поля, которые были запрошены, что сократит время анализа по сравнению со случаем, в котором мы получим подробный ответ JSON.
Избегает выполнения нескольких запросов: в случае REST API мы должны поддерживать несколько конечных точек. Например, один end point для получения «id» пользователя из /users и второй для получения уже нужной информации о пользователе из /users /<id>. Это два запроса. GraphQL уменьшит эту ситуацию до одного запроса благодаря концепции Arguments.
Resultant single Query:
query{ User(id:«abcj34»){ //Argument name subject } } |
Итак, вы уже хотите начать, но вам нужны уже работающие интерфейсы для использования на стороне клиента и другие важные инструменты. Итак, вот интересный список, который вы можете использовать прямо сейчас или добавить в закладки на будущее.
PS: Если у вас уже есть REST API и вы хотите перейти к GraphQL, вы можете использовать express-graphql, который создаст GraphQL-оболочку вокруг вашего REST API или SOAP, а затем вы можете использовать его как API-интерфейс GraphQL.
Для тестирования GraphQL на Android я сделал два проекта. Один из них – простой проект, просто отправляющий запросы по URL-адресу с помощью Retrofit с соответствующими заголовками. Второй использует GraphQL через apollo-android, который является совместимым клиентом, генерирующим Java-модели в соответствии с вашим запросом, что облегчает получение данных от API.
Начнем с настройки apollo-android и того, как его использовать для создания следующей демонстрации:
В вашем проекте build.gradle добавьте следующее:
//In your project build.gradle dependencies { classpath ‘com.android.tools.build:gradle:3.0.1’ classpath «org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.21» classpath ‘com.apollographql.apollo:gradle-plugin:0.3.2’ //Add this // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } |
Теперь перейдите в app build.gradle, добавьте следующее сверху:
apply plugin: ‘com.android.application’ apply plugin: ‘kotlin-android’ apply plugin: ‘kotlin-android-extensions’ apply plugin: ‘com.apollographql.android’ // Add this ..... ..... |
Теперь в зависимостях добавьте следующее:
implementation ‘com.apollographql.apollo:apollo-runtime:0.3.2’ implementation «com.apollographql.apollo:apollo-android-support:0.3.2» |
После этого синхронизируйте свой проект.
Для кодогенерации моделей два файла должны быть добавлены в проект – первый с расширением .graphql, а второй schema.json, который также является источником для генерации кода моделей.
1. npm—install apollo—codegen //For installing the apollo-codegen 2. For sending the introspection query and getting the schema.json execute following: apollo—codegen download—schema https://api.github.com/graphql —output schema.json —header «Authorization: Bearer <Your TOKEN here>» |
query FindQuery($owner:String!,$name:String!){ repository(owner:$owner, name:$name) { name description forkCount url } } |
Создайте каталог с именем «graphql» в папке /main вашего проекта на одном уровне с каталогом java и вставьте оба файла. Теперь сделайте ребилд проекта, и когда сборка закончится, вы увидите автоматически созданные модели в build/generated, как показано на следующем скриншоте:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | private fun setupApollo(): ApolloClient { val okHttp = OkHttpClient .Builder() .addInterceptor({ chain -> val original = chain.request() val builder = original.newBuilder().method(original.method(), original.body()) builder.addHeader(«Authorization» , «Bearer « + BuildConfig.AUTH_TOKEN) chain.proceed(builder.build()) }) .build() return ApolloClient.builder() .serverUrl(BASE_URL) .okHttpClient(okHttp) .build() } |
Apollo-android использует okhttp-клиент для отправки запросов и получения ответов. Для этого настройте клиент, добавив соответствующие заголовки, а также перехватчик okhttp. Добавьте соответствующий okHttpClient в ApolloClient.builder (), как показано выше.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | client=setupApollo() client.query(FindQuery //From the auto generated class .builder() .name(repo_name_edittext.text.toString()) //Passing required arguments .owner(owner_name_edittext.text.toString()) //Passing required arguments .build()) .enqueue(object : ApolloCall.Callback<FindQuery.Data>() { override fun onFailure(e: ApolloException) { Log.info(e.message.toString()) } override fun onResponse(response: Response<FindQuery.Data>) { Log.info(» « + response.data()?.repository()) runOnUiThread({ progress_bar.visibility = View.GONE name_text_view.text = String.format(getString(R.string.name_text), response.data()?.repository()?.name()) description_text_view.text = String.format(getString(R.string.description_text), response.data()?.repository()?.description()) forks_text_view.text = String.format(getString(R.string.fork_count_text), response.data()?.repository()?.forkCount().toString()) url_text_view.text = String.format(getString(R.string.url_count_text), response.data()?.repository()?.url().toString()) }) } }) |
Из клиента создайте запрос, как показано выше, и передайте соответствующие аргументы. Обработайте результат, как показано выше, и соответственно измените UI.
Весь проект для изучения вы можете найти здесь.