Свежий взгляд
на разработку API

Притульский Анатолий

PHP Developer из Travellizy

https://github.com/nepster-web/conf-info/tree/master/2017/CodeID-GraphQL

О себе

  • PHP Developer
  • Стартапер

Мультиканальный, комплексный сервис в индустрии путешествий, который работает с такими сегментами рынка как: отели, авиа и ж/д билеты, круизы, трансферы, а также рестораны, концерты и другие виды досуга.

  • Стартап
  • PHP 7.1
  • Не в продакшене

API

(Application Programming Interface)

Говорим о API
подразумеваем REST!?

REST — архитектурная парадигма

Representational State Transfer
«передача состояния представления»

Минусы REST API

  • Не существует какого-то единого стандарта, который бы полностью описывал REST.
  • Множество запросов для получения необходимых данных:
    • GET /books/:id
    • GET /books/:id/comments
    • GET /books/:id/author
  • Почти RESTful
  • ...

RESTful - это сложно

Как вариант: JSON API

http://jsonapi.org

JSON API

  • Стандартизирован
  • Не противоречит REST

Еще некоторые виды API

  • SOAP
  • OData
  • GData
  • MQL
  • SparQL
  • ???
  • ...

Популярные API

  • Почти RESTful
  • SOAP
  • ???

Что выбрать для разработки API?

GraphQL

(A query language for your API)

Что такое GraphQL?

В двух словах, GraphQL это синтаксис, который описывает как запрашивать данные, и, в основном, используется клиентом для загрузки данных с сервера.

Facebook используют GraphQL с 2012 года. А в 2015 году GraphQL стал доступен всем.

Плюсы GraphQL

  • Facebook используют GraphQL с 2012 года.
  • GraphQL решает реальные задачи.
  • Просто и очевидно.
  • Четкий и ясный API между backend и frontend.
  • Уменьшает затраты на коммуникации.
  • Все больше компаний переходит на GraphQL.

Существует несколько реализаций GraphQL

Языковая поддержка GraphQL

http://graphql.org/code/

  • PHP
  • Go
  • Java
  • JavaScript
  • C# / .NET
  • Scala
  • Python
  • Ruby
  • ...

Кто использует GraphQL?

http://graphql.org/users/

https://github.com/APIs-guru/graphql-apis

GitHub GraphQL API

https://developer.github.com/v4/explorer/

GraphQL в действии

Пример запроса

{
  hero {
    name
    friends {
      name
    }
  }
}

Результат

{
  "data": {
    "hero": {
      "name": "R2-D2",
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  }
}

Запрос с аргументами

{
  human(id: "1000") {
    name
    height(unit: FOOT)
  }
}

Результат

{
  "data": {
    "human": {
      "name": "Luke Skywalker",
      "height": 5.6430448
    }
  }
}

Запрос

query($id String!) {
  human(id: $id) {
    name
    height(unit: FOOT)
  }
}

Параметры

{"id": "1000"}

Результат

{
  "data": {
    "human": {
      "name": "Luke Skywalker",
      "height": 5.6430448
    }
  }
}

Пример мутации

mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}

Параметры

{
  "ep": "JEDI",
  "review": {
    "stars": 5,
    "commentary": "This is a great movie!"
  }
}

Результат

{
  "data": {
    "createReview": {
      "stars": 5,
      "commentary": "This is a great movie!"
    }
  }
}

GraphQL в PHP

https://github.com/webonyx/graphql-php

Frameworks

Getting Started

http://webonyx.github.io/graphql-php/getting-started/

Первый запрос

query {
  echo(message: "Hello World")
}

Object Type

use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;

$queryType = new ObjectType([
    'name' => 'Query',
    'fields' => [
        'echo' => [
            'type' => Type::string(),
            'args' => [
                'message' => Type::nonNull(Type::string()),
            ],
            'resolve' => function ($root, $args) {
                return $root['prefix'] . $args['message'];
            }
        ],
    ],
]);

Endpoint

graphql.php

use GraphQL\GraphQL;
use GraphQL\Schema;

// Request data
// $query - GET or file_get_contents('php://input')
// $variables - GET or file_get_contents('php://input')
// ------------

$schema = new Schema(['query' => $queryType]);

try {
    $rootValue = ['prefix' => 'You said: '];
    $result = GraphQL::executeAndReturnResult($schema, $query, $rootValue, null, $variables);
    $output = $result->toArray();
} catch (\Exception $e) {
    $output = ['errors' => [['message' => $e->getMessage()]]];
}

header('Content-Type: application/json');
echo json_encode($output);

Проверить

php -S localhost:8000 simple1.php
curl http://localhost:8080 -d '{"query": "query { echo(message: \"Hello World\") }" }'

или

http://localhost/simple1.php?query=query{echo(message:"Hello World")}

Результат

{
    "data": {
        "echo": "You said: Hello World"
    }
}

Примеры

https://github.com/nepster-web/conf-info/tree/master/2017/CodeID-GraphQL/demo

Подробная документация

http://webonyx.github.io/graphql-php/

Перевод на русский

http://graphql.org/learn/

https://github.com/nepster-web/GraphQL-ru

An in-browser IDE for
exploring GraphQL.

https://github.com/graphql/graphiql

Static page generator for documenting GraphQL Schema.

https://github.com/2fd/graphdoc

Почитать:


Делаем GraphQL API на PHP и MySQL.

Вопросы

https://github.com/nepster-web/conf-info/tree/master/2017/CodeID-GraphQL