您好我已经构建了一个aiohttp应用程序,它可以作为运行周期性任务的自治系统。返回json&获取运营状态的文本回复&支持使用各种GET,PUT和EX来接收任务的触发器。 POST请求。
例如。我已经实现了一个GET请求,用于检索当前运行的任务列表作为json响应
我想使用reactjs UI作为前端,消耗我的aiohttp应用程序的请求。这个应用程序应该像aiohttp应用程序的管理面板。
我看到这里有两个架构选项 -
选项1。将反应应用程序嵌入到aiohttp应用程序的代码库&让aiohttp / gunicorn作为一个服务器服务整个项目
选项2 即可。将aiohttp后端与反应前端分开
而不是让aiohttp提供静态文件&对于react应用程序的html,我希望通过在单独的docker容器上运行reactjs应用程序并实现以下预期行为
来实现关注点的逻辑分离反应应用节目"后端不可用"在UI组件中依赖于&从aiohttp后端实现的API中提取数据
这也有助于反应前端与我的堆栈中的其他其他API集成(例如docker),这样我就可以为我的整个堆栈构建一个完整的管理界面
我无法找到一个帮助我为这样的应用程序实现延迟加载的反应前端的succint示例(还需要了解这是否可以使用aiohttp应用程序调用react应用程序的推送请求避免民意调查)
我是JS世界中的一个完全新手但是已经在python上做了很多工作,asyncio& aiohttp
问题 -
我选择了一个强大的选项(选项2)&有一些已知/常见的问题 我可以避免使用选项1?
请帮我一个简单的分步示例或如何为我的应用程序构建反应前端的工作代码回购,而不必过多地更改我的aiohttp处理程序
我可以在我的aiohttp应用程序中添加功能,以便它可以调用react应用程序来提交状态更新,而不是等待反应应用程序在下次轮询中调用UI
我确定这些问题暴露了我对这些东西如何运作的无知程度。任何帮助都非常感谢
答案 0 :(得分:1)
我想说,对于大型团队来说,将Javascript前端与Python后端结合起来是比较常见的情况,尤其是在进行基于HTTP的微服务时。如何处理例如身份验证-API网关,JWT令牌...
在一个Aiohttp后端(可通过HTTP直接访问,而不是通过Node.js代理)和一个Node.js前端的情况下-没有微服务之类的东西-我目前正在做这样的项目:pyladies-courseware,但完全是WIP(但已经有实际用户)。我还创建了一些示例/演示(主要是我的个人实验): github.com/messa/aiohttp-nextjs-demo-chat,github.com/messa/redis-rpc-nodejs-python-demo
最容易引起头痛的地方是:
身份验证,Cookie,CORS,OAuth等
如何将数据从后端传递到前端
如果可以将React应用静态导出(导出为HTML和JS文件),那么您当然可以直接从aiohttp甚至从CDN提供它们,并且在生产运行时不需要Node.js。
我对2019年的个人预测(或至少一个愿望:)是,将出现一个将Python后端与Javascript React UI相结合的Web框架,从而从语言和生态系统中获得最大的优势。
答案 1 :(得分:0)
沉默的downvoters吃了我的问题,所以这里是我用作权宜之计,直到我弄明白了。即使-1旅得到了这一点,至少它会帮助那些从谷歌来到这里的人。
我发现这个项目 - https://github.com/aio-libs/aiohttp_admin建立在这个项目的基础上 - https://github.com/marmelab/ng-admin所以你可以使用Angular构建一个aiohttp管理界面。
ng-admin的发布者也发布了https://github.com/marmelab/admin-on-rest - 这是我尝试使用我的aiohttp处理程序的东西(如果你想像我一样按照选项2,你将需要CORs)
aiohttp_admin有一个未解决的问题,即迁移到管理员https://github.com/aio-libs/aiohttp_admin/issues/359
所以我想这可以解决所有需要此功能的人的问题。不是reactjs程序员
这是我可以开始工作的(我仍在尝试解决分页错误,需要为我的应用程序处理自定义restclient)
以下示例应该可以帮助那些了解所有需要发生的代码的人,让他们与您的aiohttp API&如何序列化您的回复。小心使用这不起作用100%
aiohttp处理程序 -
async def get_limits(request):
"""
---
description: This end-point lists task IDs.
tags:
- scheduler
produces:
- application/json
responses:
"200":
description: successful operation returns task IDs
"405":
description: invalid HTTP Method
"""
limits = copy(request.app.limits)
pages = str(len(limits.keys()))
response_ = serialize_limits(limits)
return json_response(response_[0], headers={
"X-Total-Count": pages, "X-Content-Range": pages})
Serializer -
import toastedmarshmallow
from marshmallow import Schema, fields
class LimitSchema(Schema):
"""
schema for scheduler limits
"""
resource = fields.Str()
limit = fields.Int()
id = fields.Int()
class Limit(object):
"""
model for scheduler limits
"""
def __init__(self, resource, limit, id):
self.resource = resource
self.limit = limit
self.id = id
def __repr__(self):
return '<Limit(resource={self.resource!r})>'.format(self=self)
def serialize_limits(dict_):
"""
output a serialized version of an input dict
:param dict_:
:return:
"""
limits = []
schema = LimitSchema(many=True)
schema.jit = toastedmarshmallow.Jit
id = 0
for key, value in dict_.items():
limits.append(Limit(resource=key, limit=value, id=id))
id += 1
return schema.dump(limits)
reactjs -
list.js -
import React from 'react';
import { List, Datagrid, TextField } from 'admin-on-rest';
export const Limitlist = (props) => (
<List title="Limits" {...props}>
<Datagrid>
<TextField source="resource" />
<TextField source="limit" />
</Datagrid>
</List>
);
App.js
import React from 'react';
import { jsonServerRestClient, simpleRestClient, Admin, Resource} from 'admin-on-rest';
import myApiRestClient from './avionicsRestClient';
import { Limitlist } from './limits';
import Dashboard from './Dashboard';
const App = () => (
<Admin restClient={myApiRestClient}>
<Resource name="limits" list={Limitlist} />
</Admin>
);
export default App;