From d0b1b35a01875730a52b97c32dcacb17e5e5f0fe Mon Sep 17 00:00:00 2001 From: LJ Date: Tue, 3 Jun 2025 09:23:51 -0700 Subject: [PATCH] feat(server): `/flows/:flowName` returns both spec and schema with fp --- src/server.rs | 4 ++-- src/service/flows.rs | 33 ++++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/server.rs b/src/server.rs index 14221976d..f653dfa5c 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use crate::{lib_context::LibContext, service}; -use axum::{routing, Router}; +use axum::{Router, routing}; use tower::ServiceBuilder; use tower_http::{ cors::{AllowOrigin, CorsLayer}, @@ -47,7 +47,7 @@ pub async fn init_server( .route("/flows", routing::get(service::flows::list_flows)) .route( "/flows/:flowInstName", - routing::get(service::flows::get_flow_spec), + routing::get(service::flows::get_flow), ) .route( "/flows/:flowInstName/schema", diff --git a/src/service/flows.rs b/src/service/flows.rs index f0d243ff8..1c50678b5 100644 --- a/src/service/flows.rs +++ b/src/service/flows.rs @@ -4,9 +4,9 @@ use crate::execution::{evaluator, indexing_status, memoization, row_indexer, sta use crate::lib_context::LibContext; use crate::{base::schema::FlowSchema, ops::interface::SourceExecutorListOptions}; use axum::{ + Json, extract::{Path, State}, http::StatusCode, - Json, }; use axum_extra::extract::Query; @@ -18,20 +18,39 @@ pub async fn list_flows( )) } -pub async fn get_flow_spec( +pub async fn get_flow_schema( Path(flow_name): Path, State(lib_context): State>, -) -> Result, ApiError> { +) -> Result, ApiError> { let flow_ctx = lib_context.get_flow_context(&flow_name)?; - Ok(Json(flow_ctx.flow.flow_instance.clone())) + Ok(Json(flow_ctx.flow.data_schema.clone())) } -pub async fn get_flow_schema( +#[derive(Serialize)] +pub struct GetFlowResponse { + flow_spec: spec::FlowInstanceSpec, + data_schema: FlowSchema, + fingerprint: utils::fingerprint::Fingerprint, +} + +pub async fn get_flow( Path(flow_name): Path, State(lib_context): State>, -) -> Result, ApiError> { +) -> Result, ApiError> { let flow_ctx = lib_context.get_flow_context(&flow_name)?; - Ok(Json(flow_ctx.flow.data_schema.clone())) + let flow_spec = flow_ctx.flow.flow_instance.clone(); + let data_schema = flow_ctx.flow.data_schema.clone(); + let fingerprint = utils::fingerprint::Fingerprinter::default() + .with(&flow_spec) + .map_err(|e| api_error!("failed to fingerprint flow spec: {e}"))? + .with(&data_schema) + .map_err(|e| api_error!("failed to fingerprint data schema: {e}"))? + .into_fingerprint(); + Ok(Json(GetFlowResponse { + flow_spec, + data_schema, + fingerprint, + })) } #[derive(Deserialize)]