私はフラスコアプリを持っており、グラフェンを使用していくつかの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 やバックエンドの実装の詳細を知る必要がないエンドユーザーから、グラフ クエリ言語の知識を抽象化する方法があるかどうかを把握しようとしています。ユーザーは、残りの API であるかのように JSON 要求を作成できrequests.post("http://localhost:5000/graphql-id", json={'id': 1})
、サーバーは 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)
ただし、これは少しハッキーで脆弱なようです。これを処理するための明示的またはより良い方法はありますか?