3. Власні API методи

Остання зміна 2024/05/16 12:34 автором Ashterix

Ви можете легко додавати власні API методи до RPC сервера.

Для цього вам достатньо в будь-якому місці вашого додатку зробити будь-який клас який має стати API Сервісом, цей клас має реалізувати інтерфейс Ufo\JsonRpcBundle\ApiMethod\Interfaces\IRpcService. Цей інтерфейс не навʼязує класу жодної логіки, він необхідний лише для того, щоб Symfony зрозумів, що має його сприймати як сервіс, що доступний для RPC сервера.

Реалізуйте в вашому класі будь-який публічний метод і він автоматично буде доступний як API Сервіс.

Після виконання попередніх вказівок у вас вже будуть доступні нові методи в API. За замовченням назви методів складаються з <className>.<methodName>.

Іменування класів

В разі потреби, ви можете створити кілька класів, що будуть доступні як API Сервіси. 
Враховуючи їх неймінги ​<className>.<methodName>​, рекомендую підходити до вибору назви методу як до простої вказівки що він робить, а до назви класу як до неймспейсу API методу.

Гарна практика

Класс Messenger містить методи sendEmail(), sendSms(), класс CartResolver містить методи addProduct(), getProducts(), calculateDiscount()

в API будуть доступні методи 

  • CartResolver.addProduct
  • CartResolver.getProducts
  • CartResolver.calculateDiscount
  • Messenger.sendEmail
  • Messenger.sendSms

Навіть просто поглянувши на назви методів зрозуміло що може робити ваш сервер.

Такий підхід надає можливість використовувати одноіменні методи в різних класах:

  • ProductService.create
  • ProductService.getName
  • UserService.create
  • UserService.getName

Простий старт

Наступний приклад має продемонструвати легкість додавання ваших методів до API.

Код

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
26
27
28
29
<?php
namespace App\Api\Procedures;

use Ufo\JsonRpcBundle\ApiMethod\Interfaces\IRpcService;

class ExampleApi implements IRpcService
{
public function __construct(
  // connecting some dependencies to retrieve data
   ) {}

public function getUserNameByUuid(
        string $userId
    ): string
    {
  // some logic get user info by id
  return 'some result';
    }

public function sendEmail(
        string $email,
        string $text,
        string $subject = 'Message without subject'
    ): bool
    {
  // some logic send email
  return true;
    }
}

Праворуч приклад документації, що сервер згенерує по цьому класу.

Основна інформація щодо назв параметрів, їх типів та опціональності отримується завдяки ReflectionClass, важливим є порядок аргументів методу, їх typehint. 

Документація

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{
 "methods": {
     "ExampleApi.getUserNameByUuid": {
         "name": "ExampleApi.getUserNameByUuid",
         "description": "",
         "parameters": {
             "userId": {
                 "type": "string",
                 "name": "userId",
                 "description": "",
                 "optional": false
                }
            },
         "returns": "string",
         "responseFormat": "string"
        },
     "ExampleApi.sendEmail": {
         "name": "ExampleApi.sendEmail",
         "description": "",
         "parameters": {
             "email": {
                 "type": "string",
                 "name": "email",
                 "description": "",
                 "optional": false
                },
             "text": {
                 "type": "string",
                 "name": "text",
                 "description": "",
                 "optional": false
                },
             "subject": {
                 "type": "string",
                 "name": "subject",
                 "description": "",
                 "optional": true,
                 "default": "Message without subject"
                }
            },
         "returns": "boolean",
         "responseFormat": "boolean"
        }
    }
}

Тепер можемо зробити POST запити на обидва нових метода API і подивитися на результат.

POST запити

Request
1
2
3
4
5
6
7
{
 "id": "example_request",
 "method": "ExampleApi.getUserNameByUuid",
 "params": {
     "userId": "1111"
    }
}
Response
1
2
3
4
5
{
 "id": "example_request",
 "result": "some result",
 "jsonrpc": "2.0"
}

 

Request
1
2
3
4
5
6
7
8
9
{
 "id": "example_request",
 "method": "ExampleApi.sendEmail",
 "params": {
     "email": "user@example.com",
     "subject": "This is test mail",
     "text": "Hi! This is test send mail by API"
    }
}
Response
1
2
3
4
5
{
 "id": "example_request",
 "result": true,
 "jsonrpc": "2.0"
}

 

Для спрощення сприйняття документації, всі подальші приклади буду надавати на одному методі (sendEmail)

Опис методів та параметрів

Документатор спирається на всі наявні дані, що належать методу та його аргументам (назви, типи вхідних і вихідних даних, докблоки). Тож, опис методів і параметрів можна збагатити за рахунок докблоків.

Додамо опис методу і параметрів.

Код

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
// ...    
   /**
     * A method for sending an email message
     * @param string $email The email address
     * @param string $text Message body
     * @param string $subject Optional message subject parameter
     * @return bool
     */

 public function sendEmail(
        string $email,
        string $text,
        string $subject = 'Message without subject'
    ): bool
    {
     // some logic send email
     return true;
    }

// ...

Зверніть увагу на документацію, тепер в ній відображається додаткова інформація про метод і його параметри.

 

Документація

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
26
27
28
29
30
31
{
 "methods": {
     "ExampleApi.sendEmail": {
         "name": "ExampleApi.sendEmail",
         "description": "A method for sending an email message",
         "parameters": {
             "email": {
                 "type": "string",
                 "name": "email",
                 "description": "The email address",
                 "optional": false
                },
             "text": {
                 "type": "string",
                 "name": "text",
                 "description": "Message body",
                 "optional": false
                },
             "subject": {
                 "type": "string",
                 "name": "subject",
                 "description": "Optional message subject parameter",
                 "optional": true,
                 "default": "Message without subject"
                }
            },
         "returns": "boolean",
         "responseFormat": "boolean"
        }
    }
}

RPC attributes

Для більш гнучкого налаштування ваших методів API JsonRpcBundle використовує такий інструмент як php атрибути

За допомогою спеціалізованих атрибутів ви можете:

  • налаштувати псевдоніми для методів;
  • вказати формат відповіді для методів (якщо відповідь у вигляді масива, обʼєкта або колекції обʼєктів);
  • налаштувати валідацію вхідних параметрів;
  • налаштувати кешування відповідей.

Докладніше про ці атрибути: