技术派:谁说API网关只能集成REST APIs?

一、API网关对API的集成

REST APIs的特点有:

  • 数据驱动
  • 允许多种数据格式(JSON,XML,文本)
  • 使用HTTPS协议的安全性
  • 轻量级框架

API的REST不适用的场景:

  • 使用非HTTP协议
  • 有状态
  • 受限于HTTP动词太少

接下来,我来看一种非REST APIs协议--SOAP。

WebService有两种方式,一是SOAP协议方式,在这种方式下需要WSDL,UDDI等,二是REST方式,这种方式不需要WSDL,UDDI等。

SOAP(原为Simple Object Access Protocol的首字母缩写,即简单对象访问协议)是交换数据的一种协议规范,使用在计算机网络Web服务(web service)中,交换带结构信息。SOAP为了简化网页服务器(Web Server)从XML数据库中提取数据时,节省去格式化页面时间,以及不同应用程序之间按照HTTP通信协议,遵从XML格式执行资料互换,使其抽象于语言实现、平台和硬件。

用一个简单的例子来说明SOAP使用过程,一个SOAP消息可以发送到一个具有Web Service功能的Web站点,例如,一个含有房价信息的数据库,消息的参数中标明这是一个查询消息,此站点将返回一个XML格式的信息,其中包含了查询结果(价格,位置,特点,或者其他信息)。由于数据是用一种标准化的可分析的结构来传递的,所以可以直接被第三方站点所利用。

SOAP它的特点有:

  • 功能驱动
  • WS-Security
  • 调用不能被缓存
  • 重载荷
  • XML数据格式

其他类型的非REST APIs协议还有:

Apache Thrift、Apache Spark and Python、Apache Avro

其中,Apache Thrift的特点有:

  • 接口定义语言
  • 多种目标语言
  • 低级传输(套接字,管道等)
  • 多种协议(JSON,紧凑型,二进制等)
  • 示例:Facebook FBOSS API,Evernote SDK,Elasticsearch API

Evernote就是印象笔记的国际版,这个我天天在用:

在3Scale中,我们可以通过 Fuse 作为集成平台,将非REST APIs集成进来。Fuse既可以集成REST也可以集成非REST的API:

  • Camel route exposing REST/HTTP endpoint
  • Camel producer endpoint using non-REST endpoin

也就说说,对于如SOAP类的API,我们会将它和Fuse进行集成,然后再将Fuse集成到API网关上。

二、实验验证

本实验中,我们部署一个SOAP-based JEE application。

我们先看一下应用的web service定义:

<wsdl:portType name="Stores">

<wsdl:operation name="getAllStores">

<wsdl:input message="tns:getAllStoresRequest"/>

<wsdl:output message="tns:getAllStoresResponse"/>

</wsdl:operation>

<wsdl:operation name="getStore">

<wsdl:input message="tns:getStoreRequest"></wsdl:input>

<wsdl:output message="tns:getStoreResponse"></wsdl:output>

</wsdl:operation>

<wsdl:operation name="createStore">

<wsdl:input message="tns:createStoreRequest"></wsdl:input>

<wsdl:output message="tns:createStoreResponse"></wsdl:output>

</wsdl:operation>

<wsdl:operation name="deleteStore">

<wsdl:input message="tns:deleteStoreRequest"></wsdl:input>

<wsdl:output message="tns:deleteStoreResponse"></wsdl:output>

</wsdl:operation>

</wsdl:portType>

<wsdl:binding name="StoresSOAP" type="tns:Stores">

查看源码:

查看SOAP web service的实施部分(我们看到源码中的四个public class最终会在前端展现):

@WebService(endpointInterface="com.redhat.service.Stores")

public class StoresWS implements Stores {

@Inject

StoreDao storeDAO;

@Override

public String createStore(Store store) {

store = new Store(store.getStoreName(),store.getStoreLat(),store.getStoreLong());

storeDAO.createStore(store);

return "Store ID:" + store.getStoreID() + " CREATED";

}

@Override

public StringdeleteStore(int storeID) {

storeDAO.deleteStore(storeID);

return "Store ID: " + storeID + " DELETED";

}

@Override

public Store getStore(int storeID) {

return storeDAO.getStoreById(storeID);

}

@Override

public StoresType getAllStores() {

StoresType st = new StoresType();

st.store = storeDAO.getAll();

return st;

}

}

这个应用将会部署在基于Oenshift的EAP上。

接下来,部署应用。先创建一个部署应用的project:

创建一个部署应用的模板:

接下来,部署应用:

--> Deploying template "david-stores-api/stores-soap" to project david-stores-api

Red Hat JBoss EAP 7.0 (no https)

---------

Stores SOAP Template.

A new EAP 7 based application has been created in your project.

* With parameters:

* Application Name=stores-soap

* Custom http Route Hostname=stores-api-david.apps.na1.openshift.opentlc.com

* Git Repository URL=https://github.com/gpe-mw-training/3scale_development_labs

* Git Reference=master

* Context Directory=Stores

* Queues=

* Topics=

* A-MQ cluster password=1wWTWDuk # generated

* Github Webhook Secret=GCubd7Tr # generated

* Generic Webhook Secret=hi5Aiw2r # generated

* ImageStream Namespace=openshift

* JGroups Cluster Password=RsIIhtvr # generated

* Deploy Exploded Archives=false

* Maven mirror URL=

* ARTIFACT_DIR=

* DATABASE_SERVICE_NAME=storesdb

--> Creating resources ...

configmap "create-db" created

secret "storesdb" created

service "storesdb" created

deploymentconfig "storesdb" created

service "stores-soap" created

route "stores-soap" created

imagestream "stores-soap" created

buildconfig "stores-soap" created

deploymentconfig "stores-soap" created

--> Success

Build scheduled, use 'oc logs -f bc/stores-soap' to track its progress.

Run 'oc status' to view your app.

查看应用的部署结果:

查看应用的路由:

通过浏览器进行访问:http://stores-api-david.apps.na1.openshift.opentlc.com/StoresWS?wsdl

接下来,我们使用一个在线的web based soap客户端:

输入刚才的地址进行浏览:

可以看到应用web service定义的内容(我们看到源码中的四个public class在前端展现):

点击call function,输出结果是:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getAllStoresResponse xmlns:ns2="http://www.rhmart.com/Stores/"><Stores><store><storeID>1</storeID><storeName>Downtown
  Store</storeName><storeLat>-34.6052704</storeLat><storeLong>-58.3791766</storeLong></store><store><storeID>2</storeID><storeName>EastSide
  Store</storeName><storeLat>-34.5975668</storeLat><storeLong>-58.3710199</storeLong></store></Stores></ns2:getAllStoresResponse></soap:Body></soap:Envelope>

接下来,我们部署fuse:

oc project $OCP_PROJECT_PREFIX-stores-api

oc create -f $HOME/lab/3scale_development_labs/templates/stores-fis.json

oc new-app --template=stores-fis --param ROUTE_HOST=stores-fis-$OCP_PROJECT_PREFIX.$OCP_WILDCARD_DOMAIN

fis构建并部署成功。

接下来,登录Openshift web console,查看fsi pod,打开java console:

查看路由信息:

我们可以看到,fuse的route已经将soap应用的各个功能模块( createStore、deleteStore、getAllStores、getStore)集成:

在源码层,一个路由调用SOAP的方法是:

<route customId="true" id="soapRoute">

<from customId="true" id="_from5" uri="direct:soap"/>

<toD customId="true" id="tod" uri="cxf:bean:wsStores?defaultOperationName=${header.soapMethod}&amp;exchangePattern=InOut"/>

<setBody customId="true" id="_setBodySoap">

<simple>${body[0]}</simple>

</setBody>

<setHeader customId="true" headerName="Content-Type" id="_setHeaderContextType">

<constant>application/json</constant>

</setHeader>

</route>

将curl请求发送到stores-fis路由以调用REST Web服务,并检查是否调用了SOAP Web服务并将响应转换为application / json:

我们查看OCP中fuse的路由:

$ curl -k stores-fis-david.apps.na1.openshift.opentlc.com/allstores

{"store":[{"storeID":1,"storeName":"Downtown\n Store","storeLat":-34.6052704,"storeLong":-58.3791766},{"storeID":2,"storeName":"EastSide\n Store","storeLat":-34.5975668,"storeLong":-58.3710199}]}

截至到目前,REST-SOAP Camel代理现在已正确部署,我们可以开始配置APIcast网关以使用此REST端点与SOAP Web服务进行通信。

创建应用到apicast-staging and apicast-production的路由:

接下来,我们到3scale上对应用进行集成.

创建应用:

创建app plan:

发布plan:

创建应用,选择刚才创建的app plan:

接下来,对应用进行API集成:

http://stores-fis-david.apps.na1.openshift.opentlc.com:80

https://stores-staging-apicast-david.apps.na1.openshift.opentlc.com:443

https://stores-production-apicast-david.apps.na1.openshift.opentlc.com:443

测试集成成功:

Prompt应用到生产:

接下来,我们分别访问两个环境中的引用:

Staging Environment

https://stores-staging-apicast-david.apps.na1.openshift.opentlc.com:443

Production Environment

https://stores-production-apicast-david.apps.na1.openshift.opentlc.com:443

$ curl -k "https://stores-staging-apicast-david.apps.na1.openshift.opentlc.com:443/allstores?user_key=d2a880ba1428dd8a505acae61349108f"

{"store":[{"storeID":1,"storeName":"Downtown\n Store","storeLat":-34.6052704,"storeLong":-58.3791766},{"storeID":2,"storeName":"EastSide\n Store","storeLat":-34.5975668,"storeLong":-58.3710199}]}

$ curl -k "https://stores-production-apicast-david.apps.na1.openshift.opentlc.com:443/allstores?user_key=d2a880ba1428dd8a505acae61349108f"

{"store":[{"storeID":1,"storeName":"Downtown\n Store","storeLat":-34.6052704,"storeLong":-58.3791766},{"storeID":2,"storeName":"EastSide\n Store","storeLat":-34.5975668,"storeLong":-58.3710199}]}

测试成功!

接下来,我们将Stock API部署到运行在OpenShift上的JBoss EAP容器上。 Stock数据在两个数据库:MySQL和PostgreSQL。 JBoss Data Virtualization用于提供数据虚拟化,并将组合数据视图作为OData REST服务提供。

创建stock API business service applications:

将将stock-api模板导入OpenShift环境:

oc create -f $HOME/lab/3scale_development_labs/templates/stock-api.json

将数据源环境变量security添加到项目中:

oc secret new datavirt-app-config $HOME/lab/3scale_development_labs/Stock/datasources.env

创建SA:

jboss@rhtapimgmt / $ oc create serviceaccount datavirt-service-account

serviceaccount "datavirt-service-account" created

jboss@rhtapimgmt / $ oc policy add-role-to-user view system:serviceaccount:stock-api:datavirt-service-account

role "view" added: "system:serviceaccount:stock-api:datavirt-service-account"

接下来,部署应用:

oc new-app --template=stock-api --param HOSTNAME_HTTP=stock-api-$OCP_PROJECT_PREFIX.$OCP_WILDCARD_DOMAIN

创建成功以后:

一旦API和数据库窗格正在运行,通过向端点发出请求来测试odata服务:

{"@odata.context":"$metadata#stock","value":[{"productid":1,"amount":20.0,"storeid":1},{"productid":1,"amount":30.0,"storeid":2},{"productid":2,"amount":30.0,"storeid":1},{"productid":2,"amount":14.0,"storeid":2},{"productid":3,"amount":1.0,"storeid":1},{"productid":3,"amount":40.0,"storeid":2},{"productid":4,"amount":14.0,"storeid":1},{"productid":4,"amount":100.0,"storeid":2},{"productid":5,"amount":22.0,"storeid":1},{"productid":5,"amount":2.0,"storeid":2},{"productid":6,"amount":880.0,"storeid":1},{"productid":6,"amount":10.0,"storeid":2},{"productid":7,"amount":1200.0,"storeid":1},{"productid":7,"amount":32.0,"storeid":2},{"productid":8,"amount":532.0,"storeid":1},{"productid":8,"amount":1.0,"storeid":2},{"productid":9,"amount":10.0,"storeid":1},{"productid":9,"amount":123.0,"storeid":2},{"productid":10,"amount":1.0,"storeid":1},{"productid":10,"amount":730.0,"storeid":2}]}

接下来,我们可以创建路由,将stock-api和APIcast gateway关联:

oc create route edge stock-staging-route \ --service=apicast-staging \ --hostname=stock-staging-apicast-$OCP_PROJECT_PREFIX.$OCP_WILDCARD_DOMAIN$

oc create route edge stock-production-route \ --service=apicast-production \ --hostname=stock-production-apicast-$OCP_PROJECT_PREFIX.$OCP_WILDCARD_DOMAIN

然后再将应用集成到API网关上,这次集成的时候,mapping规则增加:

API Client选择:

然后就可以通过API网关的理由访问API了。

由于操作步骤与之前类似,这里不再详细赘述。

魏新宇

  • "大魏分享"运营者、红帽资深解决方案架构师
  • 专注开源云计算、容器及自动化运维在金融行业的推广
  • 拥有MBA、ITIL V3、Cobit5、C-STAR、TOGAF9.1(鉴定级)等管理认证。
  • 拥有红帽RHCE/RHCA、VMware VCP-DCV、VCP-DT、VCP-Network、VCP-Cloud、AIX、HPUX等技术认证。

原文发布于微信公众号 - 大魏分享(david-share)

原文发表时间:2018-05-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏区块链

20种功能强大的跨平台渗透测试工具

什么是渗透测试?用来测试软件是否存在例如安全方面的漏洞,如果已经存在,会不会被入侵。 渗透测试流程: 1、列出软件或系统潜在的安全漏洞。 2、根据漏洞的严重性进...

2217
来自专栏云计算

在Heroku中部署一个Sinatra应用程序

Heroku是一个专门用于解决服务器管理问题的云应用平台。你只需构建您的应用程序,然后通过Git将其推送到Heroku就可以了。那么如何部署一个Sinatra应...

2376
来自专栏即时通讯技术

新手入门:目前为止最透彻的的Netty高性能原理和框架架构解析

Netty 是一个广受欢迎的异步事件驱动的Java开源网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。

1.3K3
来自专栏IT技术精选文摘

Netty高性能之道

1. 背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K...

2987
来自专栏挖掘大数据

Apache NiFi 简介及Processor实战应用

Apache NiFi是什么?NiFi官网给出如下解释:“一个易用、强大、可靠的数据处理与分发系统”。通俗的来说,即Apache NiFi 是一个易于使用、功能...

1.4K10
来自专栏三杯水

Codis 3.2 部署配置汇总

服务端:codis-fe------codis-dashboard------codis-proxy------codis-group------codis-s...

4793
来自专栏EAWorld

Resteasy ,从学会使用到了解原理

1、背景知识 1.1)了解Rest是什么? 1.2)了解JAX-RS是什么? 1.3)RestEasy简介 2、手把手教你使...

2724
来自专栏自由而无用的灵魂的碎碎念

解决因为卸载vmware后键盘不能使用的问题

我之前安装的是vmware workstation 7.1,虽然添加与删除程序里有卸载选项,不过不管用,无奈用windows 优化大师将其卸载了。然后手动删除一...

973
来自专栏JackieZheng

探秘Tomcat(一)——Myeclipse中导入Tomcat源码

前言:有的时候自己不知道自己是井底之蛙,这并没有什么可怕的,因为你只要蜷缩在方寸之间的井里,无数次的生活轨迹无非最终归结还是一个圆形;但是可怕的是有一天你不得...

2018
来自专栏恰同学骚年

Spring Cloud 微服务架构学习笔记与示例

本文示例基于Spring Boot 1.5.x实现,如对Spring Boot不熟悉,可以先学习我的这一篇:《Spring Boot 1.5.x 基础学习示例》...

1892

扫码关注云+社区