0

我有一个烧瓶应用程序,我正在使用石墨烯来构建一些 graphql 端点。以下代码段用于构建metadata_by_config查询。

engine = create_engine('postgres_url', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))

Base = declarative_base()
Base.query = db_session.query_property()

class MetadataModel(Base):

    __tablename__ = "metadata"

    id = Column(Integer, primary_key=True, autoincrement=True)
    created = Column(DateTime, nullable=False)
    config = Column(String(255), unique=False, nullable=False)

    def __init__(self, config, description):
        self.created = datetime.datetime.now()
        self.config = config


class Metadata(SQLAlchemyObjectType):
    class Meta:
        model = MetadataModel
        interfaces = (relay.Node, )


# Query
class QueryID(graphene.ObjectType):
    node = relay.Node.Field()

    metadata_by_id = graphene.List(Metadata, id=graphene.String())

    @staticmethod
    def resolve_metadata_by_id(parent, info, **args):
        q = args.get('id')

        metadata_query = Metadata.get_query(info)
        return metadata_query.filter(MetadataModel.id == q).all()

# schema
schema_id = graphene.Schema(query=QueryID, types=[Metadata])

app = Flask(__name__)
app.debug = True


app.add_url_rule(
    '/graphql-id',
    view_func=GraphQLView.as_view(
        'graphql-id',
        schema=schema_id,
        graphiql=True
    )
)


if __name__ == '__main__':
    app.run(host='0.0.0.0')

当我用图形查询语言执行请求时,这很好用,以下工作:

q = """
{
  metadataById (id: 1){
  id
  created
  config
}
}
"""

resp = requests.post("http://localhost:5000/graphql-id", params={'query': q})
print(resp.text)

但是,由于它是石墨烯,因此没有单独的 graphql 服务器(代码优先方法)。因此,我试图弄清楚是否有一种方法可以从最终用户那里抽象出图形查询语言知识,而用户不需要知道 gql 或后端实现细节。用户应该能够发出 JSON 请求,就像requests.post("http://localhost:5000/graphql-id", json={'id': 1})它是一个休息 API 一样,然后服务器解析 JSON 并可能在解析器方法中准备适当的查询。

我正在考虑使用重定向(暴露与 graphql 端点对话的另一个端点)来处理这种情况,并graphql-config通过在以下内容上添加条件来使端点只能在 localhost 上访问app.before_request

@app.before_request
    def before_request():
        if request.remote_addr != "127.0.0.1" and request.path == "/v1/graphql-config":
            abort(403)

但是,这似乎有点hacky和脆弱,有没有明确或更好的方法来处理这个?

4

1 回答 1

0

啊,我没有意识到我们实际上可以执行我们的模式,所以我们不需要使用GraphQLViewflask-graphql创建端点。所以我已经实现了我的端点如下:

@app.route('/getMetadata', methods=['GET'])
def getMetadata():
    data = request.get_json()
    MetaId = data["id"]
    query = '{ metadataById (id: ' + f"\"{metaId}\"" '){id created config}}'
    result = schema_id.execute(query)
    return flask.make_response(result, 200)

在这里,最终用户只需发出 JSON 请求,而无需了解 graphql 查询。

于 2020-12-16T23:07:41.490 回答