{{announcement.body}}
{{announcement.title}}

Invoking Zato Python Microservices With OpenAPI

DZone 's Guide to

Invoking Zato Python Microservices With OpenAPI

See how to invoke Zato Python microservices with OpenAPI.

· Integration Zone ·
Free Resource

One of the exciting additions of the upcoming Zato 3.2 release is the ability to invoke services through OpenAPI endpoints without a need for creation of REST channels explicitly - read more for details.

Python Code

Supposing we have a service such as below - note that it is uses SimpleIO and that each of its input/output attributes is documented in the docstring - we would like to invoke it from an external application while delegating to Zato as much effort involved in it as possible.

Java
 




x
29


 
1
# -*- coding: utf-8 -*-
2
# Zato
3
from zato.server.service import Service
4
class GetUserAccount(Service):   
5
    """ Returns user account details based on user ID and type.
6
    """   
7
    name = 'api.get.user.account'
8
   
9
    class SimpleIO:      
10
        """
11
        * account_id - ID of the user account to return
12
        * user_type - Type of the user the account belongs to
13
        * user_name - Name of the user to whom account_id belongs
14
        * needs_review - A flag indicating whether the account needs to be reviewed
15
        """       
16
        input_required = 'account_id', 'user_type'      
17
        output_required = 'account_name', 'needs_review'
18
  
19
    def handle(self):
20
        # Local aliases     
21
        account_id = self.request.input.account_id     
22
        user_type  = self.request.input.user_type
23
       
24
        # In reality, additional work would be carried out here first ..   
25
        self.logger.info('Returning data for `%s` (%s)', account_id, user_type )
26
     
27
        # .. produce the output now.      
28
        self.response.payload.user_name = 'my.user'     
29
        self.response.payload.needs_review = True


REST Channels

We will not pursue this path in this article but, in other circumstances, we could just create a REST channel for the service. This is great and it works perfectly fine, always letting one adjust many options, such as caching or rate-limiting. 

Creating a REST channel

However, today, we will auto-create API definitions using OpenAPI.

Creating OpenAPI Specifications

Documentation, including OpenAPI specifications, can be created from the command line, as below:

Java
 




xxxxxxxxxx
1


 
1
$ zato apispec /path/to/server \
2
--dir /my/output/directory     \
3
--include api.*                \
4
--tags public                  \
5
--verbose


What we will find in the output directory is a Sphinx project with human-readable documentation, which is nice in itself, along with formal specifications, including OpenAPI.

Sphinx documentation

Sphinx documentation

Inspecting the OpenAPI Specification

Upon downloading the openapi.yaml file we can confirm that it is a formal specification of the APIs exposed - including request and response schemas as well as endpoint addresses.

Note that, because we are using SimpleIO, the specification includes description of parameters and the parameters have expected data types, e.g. account_id is an integer while needs_review is a boolean.

Java
 




xxxxxxxxxx
1
56


 
1
components
2
  schemas:  
3
    request_api_get_user_account:    
4
      properties:     
5
        account_id:     
6
          description: ID of the user account to return    
7
          format: int32       
8
          type: integer    
9
        user_type:     
10
          description: Type of the user the account belongs to    
11
          format: string         
12
          type: string  
13
        required:   
14
        - account_id    
15
        - user_type     
16
        title: Request object for api.get.user.account   
17
        type: object   
18
    response_api_get_user_account:    
19
      properties:       
20
        needs_review:       
21
          description: A flag indicating whether the account needs to be reviewed      
22
          format: boolean     
23
          type: boolean     
24
        user_name:      
25
          description: Name of the user to whom account_id belongs     
26
          format: string       
27
          type: string    
28
      required:     
29
     - user_name   
30
     - needs_review  
31
     title: Response object for api.get.user.account     
32
     type: object 
33
paths:  
34
  /zato/api/invoke/api.get.user.account
35
    post:    
36
      consumes:     
37
      - application/json   
38
      operationId: post__zato_api_invoke_api_get_user_account  
39
      requestBody:      
40
        content:        
41
          application/json:      
42
            schema:          
43
              $ref: '#/components/schemas/request_api_get_user_account'    
44
        required: true    
45
      responses:   
46
        '200':       
47
          content:         
48
            application/json:        
49
              schema:             
50
                $ref: '#/components/schemas/response_api_get_user_account' 
51
info
52
  title: API spec 
53
  version: '1.0' 
54
openapi: 3.0.2 
55
servers
56
- url: http://localhost:11223


Using OpenAPI

With the specification downloaded, we can start to invoke our service immediately - in this case, we will use Postman. Essentially, import a definition, choose the desired service, provide input data and click the "Send" button.

Afterwards, we can also confirm in Zato server logs that the request was processed correctly.

Naturally, Postman is just a sample client utilising the OpenAPI specification - clients in other languages can be easily used as well, including Python, Java, .NET, JavaScript and more.

Postman - import OpenAPI



Postman - select an endpoint


Postman - invoke an endpoint

Zato logs

Even More Protocols

The above suffices for external clients to invoke your services purely based on their Python definitions with endpoints, documentation and specifications auto-generated by Zato.

But there is more. Have you noticed that nothing in the service used is specific to REST, OpenAPI or HTTP for that matter?

That is one of the benefits of using Zato - such a service is completely reusable across a range of other protocols, which means that it can exposed as-is through other channels, e.g. IBM MQ, AMQP, SOAP, WebSockets, Publish/Subscribe topics, Scheduler, File transfer and many more.

Be sure to check the Zato documentation for more details!

Topics:
integration, microservice, openapi, python, soa, tutorial, zato

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}