From 1e66068d1744d8591d8476393fd4c3eee2767694 Mon Sep 17 00:00:00 2001 From: Jens Neuse Date: Thu, 11 Jun 2026 16:18:06 +0200 Subject: [PATCH 1/6] feat(router): engine flags for dataflow execution and execution plan scheduling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds EngineExecutionConfiguration.EnableDataflowExecution (ENGINE_ENABLE_DATAFLOW) and EnableExecutionPlanScheduling (ENGINE_ENABLE_SCHEDULE_TREE), both default off. The first enables the engine's per-FetchID dataflow executor for flat query plans; the second plans operations through the dominance-based schedule-tree scheduler (constructor-injected into OperationPlanner — no env reads in the planner). Schedule-tree plans are nested, and the dataflow executor structurally rejects nested plans and falls back to the wave executor, so the combination degrades safely (warn-logged at startup). TestExecutionPlanSchedulingPlumbing pins the full response of a multi-subgraph operation under the scheduler, proving config -> engine plumbing and the nested Parallel(Sequence...) plan shape end to end. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../execution_plan_scheduling_test.go | 42 ++++++++++++++ router/core/executor.go | 15 +++++ router/core/graph_server.go | 3 +- router/core/operation_planner.go | 27 +++++++-- router/pkg/config/config.go | 7 ++- router/pkg/config/config.schema.json | 10 ++++ router/pkg/config/config_test.go | 55 +++++++++++++++++++ .../pkg/config/testdata/config_defaults.json | 2 + router/pkg/config/testdata/config_full.json | 2 + 9 files changed, 155 insertions(+), 8 deletions(-) create mode 100644 router-tests/operations/execution_plan_scheduling_test.go diff --git a/router-tests/operations/execution_plan_scheduling_test.go b/router-tests/operations/execution_plan_scheduling_test.go new file mode 100644 index 0000000000..9cd71b66c5 --- /dev/null +++ b/router-tests/operations/execution_plan_scheduling_test.go @@ -0,0 +1,42 @@ +package integration + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/wundergraph/cosmo/router-tests/testenv" + "github.com/wundergraph/cosmo/router/pkg/config" +) + +// TestExecutionPlanSchedulingPlumbing proves the EnableExecutionPlanScheduling +// config reaches the engine: with the flag on and query plans included in the +// response, a multi-subgraph operation must report a NESTED schedule tree +// (Parallel containing Sequences) instead of the legacy flat wave grouping. +func TestExecutionPlanSchedulingPlumbing(t *testing.T) { + t.Parallel() + + testenv.Run(t, &testenv.Config{ + ModifyEngineExecutionConfiguration: func(cfg *config.EngineExecutionConfiguration) { + cfg.EnableExecutionPlanScheduling = true + cfg.Debug.AlwaysIncludeQueryPlan = true + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query Requires { + products { + __typename + ... on Consultancy { + lead { + __typename + id + derivedMood + } + isLeadAvailable + } + } + }`, + }) + require.Equal(t, `{"data":{"products":[{"__typename":"Consultancy","lead":{"__typename":"Employee","id":1,"derivedMood":"HAPPY"},"isLeadAvailable":false},{"__typename":"Cosmo"},{"__typename":"SDK"}]},"extensions":{"queryPlan":{"version":"1","kind":"Sequence","children":[{"kind":"Single","fetch":{"kind":"Single","subgraphName":"employees","subgraphId":"0","fetchId":0,"query":"{\n products {\n __typename\n ... on Consultancy {\n lead {\n __typename\n id\n }\n __typename\n upc\n }\n }\n}"}},{"kind":"Parallel","children":[{"kind":"Sequence","children":[{"kind":"Single","fetch":{"kind":"BatchEntity","path":"products.@.lead","subgraphName":"availability","subgraphId":"5","fetchId":1,"dependsOnFetchIds":[0],"representations":[{"kind":"@key","typeName":"Employee","fragment":"fragment Key on Employee {\n __typename\n id\n}"}],"query":"query($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n isAvailable\n }\n }\n}","dependencies":[{"coordinate":{"typeName":"Employee","fieldName":"isAvailable"},"isUserRequested":false,"dependsOn":[{"fetchId":0,"subgraph":"employees","coordinate":{"typeName":"Employee","fieldName":"id"},"isKey":true,"isRequires":false}]}]}},{"kind":"Single","fetch":{"kind":"BatchEntity","path":"products","subgraphName":"employees","subgraphId":"0","fetchId":4,"dependsOnFetchIds":[0,1],"representations":[{"kind":"@requires","typeName":"Consultancy","fieldName":"isLeadAvailable","fragment":"fragment Requires_for_isLeadAvailable on Consultancy {\n lead {\n isAvailable\n }\n}"},{"kind":"@key","typeName":"Consultancy","fragment":"fragment Key on Consultancy {\n __typename\n upc\n}"}],"query":"query($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Consultancy {\n __typename\n isLeadAvailable\n }\n }\n}","dependencies":[{"coordinate":{"typeName":"Consultancy","fieldName":"isLeadAvailable"},"isUserRequested":true,"dependsOn":[{"fetchId":3,"subgraph":"employees","coordinate":{"typeName":"Consultancy","fieldName":"lead"},"isKey":false,"isRequires":true},{"fetchId":2,"subgraph":"mood","coordinate":{"typeName":"Consultancy","fieldName":"lead"},"isKey":false,"isRequires":true},{"fetchId":1,"subgraph":"availability","coordinate":{"typeName":"Consultancy","fieldName":"lead"},"isKey":false,"isRequires":true},{"fetchId":0,"subgraph":"employees","coordinate":{"typeName":"Consultancy","fieldName":"lead"},"isKey":false,"isRequires":true},{"fetchId":1,"subgraph":"availability","coordinate":{"typeName":"Employee","fieldName":"isAvailable"},"isKey":false,"isRequires":true},{"fetchId":0,"subgraph":"employees","coordinate":{"typeName":"Consultancy","fieldName":"upc"},"isKey":true,"isRequires":false}]}]}}]},{"kind":"Sequence","children":[{"kind":"Single","fetch":{"kind":"BatchEntity","path":"products.@.lead","subgraphName":"mood","subgraphId":"6","fetchId":2,"dependsOnFetchIds":[0],"representations":[{"kind":"@key","typeName":"Employee","fragment":"fragment Key on Employee {\n __typename\n id\n}"}],"query":"query($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n currentMood\n }\n }\n}","dependencies":[{"coordinate":{"typeName":"Employee","fieldName":"currentMood"},"isUserRequested":false,"dependsOn":[{"fetchId":0,"subgraph":"employees","coordinate":{"typeName":"Employee","fieldName":"id"},"isKey":true,"isRequires":false}]}]}},{"kind":"Single","fetch":{"kind":"BatchEntity","path":"products.@.lead","subgraphName":"employees","subgraphId":"0","fetchId":3,"dependsOnFetchIds":[0,2],"representations":[{"kind":"@requires","typeName":"Employee","fieldName":"derivedMood","fragment":"fragment Requires_for_derivedMood on Employee {\n currentMood\n}"},{"kind":"@key","typeName":"Employee","fragment":"fragment Key on Employee {\n __typename\n id\n}"}],"query":"query($representations: [_Any!]!){\n _entities(representations: $representations){\n ... on Employee {\n __typename\n derivedMood\n }\n }\n}","dependencies":[{"coordinate":{"typeName":"Employee","fieldName":"derivedMood"},"isUserRequested":true,"dependsOn":[{"fetchId":2,"subgraph":"mood","coordinate":{"typeName":"Employee","fieldName":"currentMood"},"isKey":false,"isRequires":true},{"fetchId":0,"subgraph":"employees","coordinate":{"typeName":"Employee","fieldName":"id"},"isKey":true,"isRequires":false}]}]}}]}]}],"normalizedQuery":"query Requires {products {__typename ... on Consultancy {lead {__typename id derivedMood} isLeadAvailable}}}"}}}`, res.Body) + }) +} diff --git a/router/core/executor.go b/router/core/executor.go index 785aaadb6c..c373f527df 100644 --- a/router/core/executor.go +++ b/router/core/executor.go @@ -90,9 +90,24 @@ func (b *ExecutorConfigurationBuilder) Build(ctx context.Context, opts *Executor PropagateFetchReasons: opts.RouterEngineConfig.Execution.EnableRequireFetchReasons, ValidateRequiredExternalFields: opts.RouterEngineConfig.Execution.ValidateRequiredExternalFields, SetDeduplicationShardCountToGOMAXPROCS: true, + EnableDataflowExecution: opts.RouterEngineConfig.Execution.EnableDataflowExecution, AllowCustomExtensionProperties: opts.RouterEngineConfig.SubgraphExtensionPropagation.Enabled, } + if opts.RouterEngineConfig.Execution.EnableDataflowExecution { + b.logger.Info("experimental dataflow executor enabled (ENGINE_ENABLE_DATAFLOW)") + if opts.RouterEngineConfig.Execution.EnableExecutionPlanScheduling { + // Informational only: the single source of truth for both-flags behavior is + // the engine-level structural guard (the dataflow executor rejects nested + // schedule-tree plans and falls back to the schedule-tree executor). + b.logger.Warn("ENGINE_ENABLE_DATAFLOW and ENGINE_ENABLE_SCHEDULE_TREE are both set: " + + "nested schedule-tree plans run the schedule-tree executor; dataflow applies only to plans that remain flat") + } + } + if opts.RouterEngineConfig.Execution.EnableExecutionPlanScheduling { + b.logger.Info("experimental schedule-tree planner enabled (ENGINE_ENABLE_SCHEDULE_TREE)") + } + if opts.ApolloCompatibilityFlags.ValueCompletion.Enabled { options.ResolvableOptions.ApolloCompatibilityValueCompletionInExtensions = true } diff --git a/router/core/graph_server.go b/router/core/graph_server.go index af206997be..c7b335164d 100644 --- a/router/core/graph_server.go +++ b/router/core/graph_server.go @@ -1542,7 +1542,8 @@ func (s *graphServer) buildGraphMux( } } - operationPlanner := NewOperationPlanner(executor, gm.planCache, gm.planFallbackCache, s.planningDurationOverride) + operationPlanner := NewOperationPlanner(executor, gm.planCache, gm.planFallbackCache, s.planningDurationOverride, + s.engineExecutionConfiguration.EnableExecutionPlanScheduling) // We support the MCP only on the base graph. Feature flags are not supported yet. if opts.IsBaseGraph() && s.mcpServer != nil { diff --git a/router/core/operation_planner.go b/router/core/operation_planner.go index f9da57396f..96265f2994 100644 --- a/router/core/operation_planner.go +++ b/router/core/operation_planner.go @@ -37,6 +37,11 @@ type OperationPlanner struct { // planningDurationOverride, when set, replaces the measured planning duration. // This is used in tests to simulate slow queries. planningDurationOverride func(content string) time.Duration + + // enableExecutionPlanScheduling plans operations through the dominance-based + // schedule-tree scheduler (postprocess.WithBuildScheduleTree). Static per + // router process; config reload rebuilds the mux. + enableExecutionPlanScheduling bool } type operationPlannerOpts struct { @@ -59,13 +64,15 @@ func NewOperationPlanner( planCache ExecutionPlanCache[uint64, *planWithMetaData], fallbackCache *slowplancache.Cache[*planWithMetaData], planningDurationOverride func(content string) time.Duration, + enableExecutionPlanScheduling bool, ) *OperationPlanner { return &OperationPlanner{ - planCache: planCache, - executor: executor, - trackUsageInfo: executor.TrackUsageInfo, - slowPlanCache: fallbackCache, - planningDurationOverride: planningDurationOverride, + planCache: planCache, + executor: executor, + trackUsageInfo: executor.TrackUsageInfo, + slowPlanCache: fallbackCache, + planningDurationOverride: planningDurationOverride, + enableExecutionPlanScheduling: enableExecutionPlanScheduling, } } @@ -90,7 +97,15 @@ func (p *OperationPlanner) planOperation(content string, name string, includeQue if report.HasErrors() { return nil, &reportError{report: &report} } - post := postprocess.NewProcessor(postprocess.CollectDataSourceInfo()) + postOpts := []postprocess.ProcessorOption{postprocess.CollectDataSourceInfo()} + if p.enableExecutionPlanScheduling { + // Experimental: dominance-based plan-time scheduler. Replaces the legacy + // orderSequenceByDependencies+createParallelNodes wave grouping with a nested + // Parallel(Sequence...) schedule tree that is provably never slower under any + // per-fetch duration vector (see graphql-go-tools docs/adr/0001-query-plan-scheduler.md). + postOpts = append(postOpts, postprocess.WithBuildScheduleTree()) + } + post := postprocess.NewProcessor(postOpts...) post.Process(preparedPlan) return &planWithMetaData{ diff --git a/router/pkg/config/config.go b/router/pkg/config/config.go index faec91db69..0a25bc6734 100644 --- a/router/pkg/config/config.go +++ b/router/pkg/config/config.go @@ -460,7 +460,12 @@ type EngineExecutionConfiguration struct { EnableSubgraphFetchOperationName bool `envDefault:"false" env:"ENGINE_ENABLE_SUBGRAPH_FETCH_OPERATION_NAME" yaml:"enable_subgraph_fetch_operation_name"` DisableVariablesRemapping bool `envDefault:"false" env:"ENGINE_DISABLE_VARIABLES_REMAPPING" yaml:"disable_variables_remapping"` EnableRequireFetchReasons bool `envDefault:"false" env:"ENGINE_ENABLE_REQUIRE_FETCH_REASONS" yaml:"enable_require_fetch_reasons"` - SubscriptionFetchTimeout time.Duration `envDefault:"30s" env:"ENGINE_SUBSCRIPTION_FETCH_TIMEOUT" yaml:"subscription_fetch_timeout,omitempty"` + // EnableDataflowExecution and EnableExecutionPlanScheduling deviate from the + // env-name-derives-from-field convention: the env tags are pinned to the names + // the benchmark suite, byte-identity gate, and 4-mode test driver key on. + EnableDataflowExecution bool `envDefault:"false" env:"ENGINE_ENABLE_DATAFLOW" yaml:"enable_dataflow_execution"` + EnableExecutionPlanScheduling bool `envDefault:"false" env:"ENGINE_ENABLE_SCHEDULE_TREE" yaml:"enable_execution_plan_scheduling"` + SubscriptionFetchTimeout time.Duration `envDefault:"30s" env:"ENGINE_SUBSCRIPTION_FETCH_TIMEOUT" yaml:"subscription_fetch_timeout,omitempty"` // Server-side WebSocket handler options (router accepting client connections) WebSocketServerReadTimeout time.Duration `envDefault:"5s" env:"ENGINE_WEBSOCKET_SERVER_READ_TIMEOUT" yaml:"websocket_server_read_timeout,omitempty"` diff --git a/router/pkg/config/config.schema.json b/router/pkg/config/config.schema.json index 7b4ead7123..0c23ce6420 100644 --- a/router/pkg/config/config.schema.json +++ b/router/pkg/config/config.schema.json @@ -3861,6 +3861,16 @@ "default": false, "description": "Enables sending the \"fetch_reasons\" extension to upstream subgraphs (only) that explains why each field (marked with @openfed__requireFetchReasons) was requested. This flag does not expose the data to clients." }, + "enable_dataflow_execution": { + "type": "boolean", + "default": false, + "description": "Experimental. Executes query plans with the dataflow executor: per-fetch dependency gating instead of the per-wave barrier. Reduces latency under skewed subgraph latency. Response bytes are identical on the success path." + }, + "enable_execution_plan_scheduling": { + "type": "boolean", + "default": false, + "description": "Experimental. Replaces the wave-based fetch grouping with a dominance-based schedule tree computed at plan time. Reduces latency under skewed subgraph latency. Changes the query plan shape reported in extensions and ART." + }, "subscription_fetch_timeout": { "type": "string", "format": "go-duration", diff --git a/router/pkg/config/config_test.go b/router/pkg/config/config_test.go index 00cb69de18..655df23c4b 100644 --- a/router/pkg/config/config_test.go +++ b/router/pkg/config/config_test.go @@ -2235,3 +2235,58 @@ persisted_operations: require.Equal(t, "at '/persisted_operations/manifest/poll_jitter': duration must be greater or equal than 1s", js.Causes[0].Error()) }) } + +func TestEngineExecutionFlagsFromYAML(t *testing.T) { + f := createTempFileFromFixture(t, ` +version: "1" + +graph: + token: "token" + +engine: + enable_dataflow_execution: true + enable_execution_plan_scheduling: true +`) + + cfg, err := LoadConfig([]string{f}) + + require.NoError(t, err) + + require.True(t, cfg.Config.EngineExecutionConfiguration.EnableDataflowExecution) + require.True(t, cfg.Config.EngineExecutionConfiguration.EnableExecutionPlanScheduling) +} + +func TestEngineExecutionFlagsDefaultOff(t *testing.T) { + f := createTempFileFromFixture(t, ` +version: "1" + +graph: + token: "token" +`) + + cfg, err := LoadConfig([]string{f}) + + require.NoError(t, err) + + require.False(t, cfg.Config.EngineExecutionConfiguration.EnableDataflowExecution) + require.False(t, cfg.Config.EngineExecutionConfiguration.EnableExecutionPlanScheduling) +} + +func TestEngineExecutionFlagsFromEnv(t *testing.T) { + t.Setenv("ENGINE_ENABLE_DATAFLOW", "true") + t.Setenv("ENGINE_ENABLE_SCHEDULE_TREE", "true") + + f := createTempFileFromFixture(t, ` +version: "1" + +graph: + token: "token" +`) + + cfg, err := LoadConfig([]string{f}) + + require.NoError(t, err) + + require.True(t, cfg.Config.EngineExecutionConfiguration.EnableDataflowExecution) + require.True(t, cfg.Config.EngineExecutionConfiguration.EnableExecutionPlanScheduling) +} diff --git a/router/pkg/config/testdata/config_defaults.json b/router/pkg/config/testdata/config_defaults.json index 3475e2cc11..802608de23 100644 --- a/router/pkg/config/testdata/config_defaults.json +++ b/router/pkg/config/testdata/config_defaults.json @@ -472,6 +472,8 @@ "EnableSubgraphFetchOperationName": false, "DisableVariablesRemapping": false, "EnableRequireFetchReasons": false, + "EnableDataflowExecution": false, + "EnableExecutionPlanScheduling": false, "SubscriptionFetchTimeout": 30000000000, "WebSocketServerReadTimeout": 5000000000, "WebSocketServerWriteTimeout": 10000000000, diff --git a/router/pkg/config/testdata/config_full.json b/router/pkg/config/testdata/config_full.json index 3a3849cdfb..60fa09c81b 100644 --- a/router/pkg/config/testdata/config_full.json +++ b/router/pkg/config/testdata/config_full.json @@ -923,6 +923,8 @@ "EnableSubgraphFetchOperationName": true, "DisableVariablesRemapping": false, "EnableRequireFetchReasons": false, + "EnableDataflowExecution": false, + "EnableExecutionPlanScheduling": false, "SubscriptionFetchTimeout": 30000000000, "WebSocketServerReadTimeout": 5000000000, "WebSocketServerWriteTimeout": 10000000000, From 53070e542aac6faf0b672cbb240cb93a5a99b4a0 Mon Sep 17 00:00:00 2001 From: Jens Neuse Date: Thu, 11 Jun 2026 16:19:33 +0200 Subject: [PATCH 2/6] perf(router): skip per-fetch telemetry when disabled; lazy-init request context keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Engine loader hooks (OnLoad/OnFinished) skip span creation, attribute building, and metric measurement when tracing, metrics, and subgraph access logging are all disabled — header propagation still runs. The default tracer was an SDK NeverSample provider that still allocated a span per call. requestContext.keys is now lazily allocated on first Set instead of eagerly per request. Co-Authored-By: Claude Opus 4.8 (1M context) --- router/core/context.go | 5 ++-- router/core/engine_loader_hooks.go | 31 ++++++++++++++++++++----- router/core/engine_loader_hooks_test.go | 6 ++--- router/core/graph_server.go | 2 ++ 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/router/core/context.go b/router/core/context.go index b20ffdbc0c..f9dc082792 100644 --- a/router/core/context.go +++ b/router/core/context.go @@ -920,8 +920,9 @@ func buildRequestContext(opts requestContextOptions) *requestContext { } return &requestContext{ - logger: opts.requestLogger, - keys: map[string]any{}, + logger: opts.requestLogger, + // keys is lazily allocated on first Set (see Set) to avoid a per-request map + // allocation for the common case where no custom context keys are written. responseWriter: opts.w, request: opts.r, operation: opts.operationContext, diff --git a/router/core/engine_loader_hooks.go b/router/core/engine_loader_hooks.go index 13c4a6da1a..2232fd805a 100644 --- a/router/core/engine_loader_hooks.go +++ b/router/core/engine_loader_hooks.go @@ -50,6 +50,12 @@ type engineLoaderHooks struct { storeSubgraphResponseBody bool headerPropagation *HeaderPropagation + + // tracingEnabled / metricsEnabled gate the per-fetch telemetry work. When both are + // disabled (and there is no subgraph access logger), OnLoad/OnFinished skip span + // creation, attribute building, and measurements entirely — header propagation still runs. + tracingEnabled bool + metricsEnabled bool } type engineLoaderHooksRequestContext struct { @@ -65,6 +71,8 @@ func NewEngineRequestHooks( metricAttributes *attributeExpressions, storeSubgraphResponseBody bool, headerPropagation *HeaderPropagation, + tracingEnabled bool, + metricsEnabled bool, ) resolve.LoaderHooks { var tracer trace.Tracer if tracerProvider != nil { @@ -88,6 +96,8 @@ func NewEngineRequestHooks( accessLogger: logger, storeSubgraphResponseBody: storeSubgraphResponseBody, headerPropagation: headerPropagation, + tracingEnabled: tracingEnabled, + metricsEnabled: metricsEnabled, } } @@ -109,12 +119,14 @@ func (f *engineLoaderHooks) OnLoad(ctx context.Context, ds resolve.DataSourceInf return ctx } - ctx, _ = f.tracer.Start(ctx, "Engine - Fetch", - trace.WithAttributes([]attribute.KeyValue{ - rotel.WgSubgraphName.String(ds.Name), - rotel.WgSubgraphID.String(ds.ID), - }...), - ) + if f.tracingEnabled { + ctx, _ = f.tracer.Start(ctx, "Engine - Fetch", + trace.WithAttributes([]attribute.KeyValue{ + rotel.WgSubgraphName.String(ds.Name), + rotel.WgSubgraphID.String(ds.ID), + }...), + ) + } return context.WithValue(ctx, rcontext.EngineLoaderHooksContextKey, &engineLoaderHooksRequestContext{ startTime: start, @@ -153,6 +165,13 @@ func (f *engineLoaderHooks) OnFinished(ctx context.Context, ds resolve.DataSourc return } + // Fast path: with tracing, metrics, and subgraph access logging all disabled there is no + // consumer for the per-fetch span/attributes/measurements. Header propagation (above) has + // already run, so skip the remaining telemetry work and its allocations entirely. + if !f.tracingEnabled && !f.metricsEnabled && f.accessLogger == nil { + return + } + latency := time.Since(hookCtx.startTime) span := trace.SpanFromContext(ctx) diff --git a/router/core/engine_loader_hooks_test.go b/router/core/engine_loader_hooks_test.go index c81de6a0ef..f160afe4a6 100644 --- a/router/core/engine_loader_hooks_test.go +++ b/router/core/engine_loader_hooks_test.go @@ -54,7 +54,7 @@ func TestOnFinished_ClientDisconnect(t *testing.T) { tp := sdktrace.NewTracerProvider(sdktrace.WithSyncer(exporter)) store := &spyMetricStore{} - hooks := NewEngineRequestHooks(store, nil, tp, nil, nil, nil, false, nil) + hooks := NewEngineRequestHooks(store, nil, tp, nil, nil, nil, false, nil, true, true) ctx, _ := setupTestContext(t, tp) @@ -84,7 +84,7 @@ func TestOnFinished_ClientDisconnect(t *testing.T) { tp := sdktrace.NewTracerProvider(sdktrace.WithSyncer(exporter)) store := &spyMetricStore{} - hooks := NewEngineRequestHooks(store, nil, tp, nil, nil, nil, false, nil) + hooks := NewEngineRequestHooks(store, nil, tp, nil, nil, nil, false, nil, true, true) ctx, _ := setupTestContext(t, tp) @@ -111,7 +111,7 @@ func TestOnFinished_ClientDisconnect(t *testing.T) { tp := sdktrace.NewTracerProvider(sdktrace.WithSyncer(exporter)) store := &spyMetricStore{} - hooks := NewEngineRequestHooks(store, nil, tp, nil, nil, nil, false, nil) + hooks := NewEngineRequestHooks(store, nil, tp, nil, nil, nil, false, nil, true, true) ctx, _ := setupTestContext(t, tp) diff --git a/router/core/graph_server.go b/router/core/graph_server.go index c7b335164d..bde28e7fdf 100644 --- a/router/core/graph_server.go +++ b/router/core/graph_server.go @@ -1726,6 +1726,8 @@ func (s *graphServer) buildGraphMux( metricAttExpressions, exprManager.VisitorManager.IsSubgraphResponseBodyUsedInExpressions(), s.headerPropagation, + s.traceConfig != nil && s.traceConfig.Enabled, + s.metricConfig != nil && s.metricConfig.IsEnabled(), ) handlerOpts := HandlerOptions{ From d2cef8e4b7018ce77dd91d0fb71246eec9b72463 Mon Sep 17 00:00:00 2001 From: Jens Neuse Date: Thu, 11 Jun 2026 16:36:01 +0200 Subject: [PATCH 3/6] test(router-tests): drive engine execution flags from the environment in testenv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initializes EnableDataflowExecution / EnableExecutionPlanScheduling from ENGINE_ENABLE_DATAFLOW / ENGINE_ENABLE_SCHEDULE_TREE so the whole suite re-runs per engine mode without code changes (test harness only — production config is constructor-injected). ModifyEngineExecutionConfiguration still overrides per test. Co-Authored-By: Claude Opus 4.8 (1M context) --- router-tests/testenv/testenv.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/router-tests/testenv/testenv.go b/router-tests/testenv/testenv.go index b83dd451ef..c90f67594b 100644 --- a/router-tests/testenv/testenv.go +++ b/router-tests/testenv/testenv.go @@ -1371,6 +1371,12 @@ func configureRouter(ctx context.Context, listenerAddr string, testConfig *Confi } engineExecutionConfig := config.EngineExecutionConfiguration{ + // Initialized from the environment so the whole suite re-runs per engine + // mode without code changes (test harness only — production config is + // constructor-injected). ModifyEngineExecutionConfiguration still + // overrides per test. + EnableDataflowExecution: os.Getenv("ENGINE_ENABLE_DATAFLOW") == "true", + EnableExecutionPlanScheduling: os.Getenv("ENGINE_ENABLE_SCHEDULE_TREE") == "true", EnableNetPoll: true, EnableSingleFlight: true, EnableInboundRequestDeduplication: false, From a326c44f369eddb5f5d0f4559a8a90747657fb56 Mon Sep 17 00:00:00 2001 From: Jens Neuse Date: Thu, 11 Jun 2026 16:58:07 +0200 Subject: [PATCH 4/6] bench(router-tests): self-contained engine-modes benchmark suite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Byte-identity gate (one sha256 across baseline/dataflow/scheduler/both, 25 sequential + 25 concurrent requests per mode, env->config->engine plumb-through proven via log greps) plus uniform-netem and skewed-latency matrices for the three engine modes from ONE router image. Encodes the methodology that made the reference numbers trustworthy: netem limit 100000 with qdisc verification, CPU-pinned gateway, real-response readiness gates, valid_bytes per row, warmup-capped k6, interleaved median-of-3. Includes the per-path lat-proxy source. Cosmo-only by design — no competitor images or configs. Co-Authored-By: Claude Opus 4.8 (1M context) --- router-tests/bench/engine-modes/README.md | 94 + router-tests/bench/engine-modes/byteid.sh | 106 + router-tests/bench/engine-modes/k6.js | 2579 +++++++++++++++++ .../bench/engine-modes/lat-proxy/Dockerfile | 8 + .../bench/engine-modes/lat-proxy/main.go | 74 + router-tests/bench/engine-modes/skew_bench.sh | 72 + .../bench/engine-modes/skew_matrix.sh | 25 + .../bench/engine-modes/uniform_bench.sh | 106 + .../bench/engine-modes/uniform_matrix.sh | 21 + 9 files changed, 3085 insertions(+) create mode 100644 router-tests/bench/engine-modes/README.md create mode 100755 router-tests/bench/engine-modes/byteid.sh create mode 100644 router-tests/bench/engine-modes/k6.js create mode 100644 router-tests/bench/engine-modes/lat-proxy/Dockerfile create mode 100644 router-tests/bench/engine-modes/lat-proxy/main.go create mode 100755 router-tests/bench/engine-modes/skew_bench.sh create mode 100755 router-tests/bench/engine-modes/skew_matrix.sh create mode 100755 router-tests/bench/engine-modes/uniform_bench.sh create mode 100755 router-tests/bench/engine-modes/uniform_matrix.sh diff --git a/router-tests/bench/engine-modes/README.md b/router-tests/bench/engine-modes/README.md new file mode 100644 index 0000000000..7a51f60e1a --- /dev/null +++ b/router-tests/bench/engine-modes/README.md @@ -0,0 +1,94 @@ +# Engine-modes benchmark suite + +Measures the router's three engine execution modes against each other from ONE +binary, selected by env flags: + +| label | `ENGINE_ENABLE_DATAFLOW` | `ENGINE_ENABLE_SCHEDULE_TREE` | +|---|---|---| +| cosmo-baseline | false | false | +| cosmo-dataflow | true | false | +| cosmo-scheduler | false | true | + +The suite is self-contained and cosmo-only. +It exists to prove two properties on every change to the engine execution path: + +1. The flags cost NOTHING when latency is uniform (regression gate). +2. Under skewed subgraph latency the dataflow executor and the schedule-tree + scheduler collapse the median to the dependency-graph critical path + (capability gate; reference: −37% vs baseline on the workload below). + +## Provisioning + +1. Router image (from this repo): + +```bash +cd router && CGO_ENABLED=0 GOOS=linux GOARCH=$(go env GOARCH) go build -ldflags '-s -w' -o /tmp/bench-router/cosmo ./cmd/router +printf 'FROM alpine:3.20\nRUN apk add --no-cache ca-certificates\nWORKDIR /app\nCOPY cosmo /app/cosmo\nENTRYPOINT ["/app/cosmo"]\n' > /tmp/bench-router/Dockerfile +docker build -t bench-cosmo:local /tmp/bench-router +``` + +2. Subgraphs image: the Rust subgraphs from + [the hive gateways-benchmark](https://github.com/graphql-hive/gateways-benchmark) + (accounts/products/reviews/inventory on one port, 4200), built as + `bench-subgraphs:latest`. + The canonical federated query (`QUERY_FILE`) is the benchmark's `MyQuery`; + against this dataset the full response is exactly 87,599 bytes + (`EXPECTED_BYTES`). + +3. lat-proxy (skew scenario only): + +```bash +docker build -t lat-proxy:local lat-proxy/ +``` + +4. Router config dirs (execution config + minimal yaml), one per topology: + `COSMO_CFG_DIR` for the uniform scenario routes subgraphs to + `http://bench-sg:4200/`, the skew variant to + `http://lat-proxy:8080/`. + +## Run + +```bash +export QUERY_FILE=/path/to/query.json EXPECTED_BYTES=87599 +export COSMO_CFG_DIR=/path/to/cfg ROUTER_IMAGE=bench-cosmo:local + +# Gate first — abort on any divergence: +bash byteid.sh + +# Then the matrices (macOS: under caffeinate -dimsu): +RES=/tmp/results/uniform.jsonl bash uniform_matrix.sh +COSMO_CFG_DIR=/path/to/cfg-proxy RES=/tmp/results/skew.jsonl bash skew_matrix.sh +``` + +Each run appends one JSON line: rps, success, min/med/p90/p95/p99.9, cpu +avg/max, mem max, valid_bytes, label, flags. Aggregate as median-of-3 per +(scenario, label) cell; a cell whose rep RPS spread exceeds 1.1x is re-run. + +## Acceptance thresholds + +Reference machine: Apple M4 Max, OrbStack, gateway pinned to 4 CPUs / 2 GB. + +- Byte identity: `BYTEID GATE: PASS` — one sha256 across all 4 modes + (baseline/dataflow/scheduler/both), 50 requests each, exact `EXPECTED_BYTES`. +- Skew (`accounts=20,products=20,reviews=20,inventory=150`; critical path + 210 ms): dataflow AND scheduler median ≤ 225 ms at 1 VU and 64 VU, RPS ≥ 265 + at 64 VU (reference floors: 218–219 ms / 274–275 RPS); baseline median in the + 340–360 ms band (the barrier anchor). Both new modes ≈ −37% vs baseline. +- Uniform ({0,10,50,100} ms, 64 VU): all three modes within 3% of each other on + median latency AND RPS at every delay; at 0 ms ≥ 19k RPS under conditions + that reproduce the reference anchors (absolute RPS is machine-sensitive — + when anchors don't reproduce, only the within-3% relative gate applies). +- `cosmo-both-SMOKE` rows ≈ the scheduler row (safe-degradation proof). + +## Methodology notes (encoded in the scripts) + +- netem on the SUBGRAPH container's egress with `limit 100000`, qdisc verified + present after adding; gateway CPU-pinned via `--cpuset-cpus` with + `GOMAXPROCS`/`GOMEMLIMIT`; subgraphs unpinned; k6 on the same docker network + (no host NAT); closed-loop constant VUs. +- A run starts only after a real federated response of the expected size is + observed; `valid_bytes` is recorded per row. +- k6 `setup()` warmup is capped at 8 requests (`vus*2` sequential warmup + poisons `http_reqs.rate` windowing at high latency). +- Tail latencies ≥ 10x the injected delay are the macOS host-sleep signature — + invalidate the rep. diff --git a/router-tests/bench/engine-modes/byteid.sh b/router-tests/bench/engine-modes/byteid.sh new file mode 100755 index 0000000000..a39be89c7e --- /dev/null +++ b/router-tests/bench/engine-modes/byteid.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +# Byte-identity gate: the SAME federated query must return the SAME bytes from +# ONE router image across all engine-flag modes, 25 sequential + 25 concurrent +# requests each. Aborts the benchmark protocol on any divergence. +# +# Modes: baseline(off,off) dataflow(on,off) scheduler(off,on) both(on,on). +# "both" asserts safe degradation: schedule-tree plans are nested, the dataflow +# executor structurally rejects nested plans and falls back — same bytes. +# +# Plumb-through preflight per mode (LOG_LEVEL=info): when dataflow is on the +# logs must contain "dataflow executor enabled"; when the scheduler is on, +# "schedule-tree planner enabled" — proving env -> config -> engine wiring. +# +# Success-path only by design: multi-error ordering determinism is covered +# in-engine by TestDataflowErrorOrderDeterminism. +set -uo pipefail +ROUTER_IMAGE="${ROUTER_IMAGE:-bench-cosmo:local}" +SUBGRAPHS_IMAGE="${SUBGRAPHS_IMAGE:-bench-subgraphs:latest}" +COSMO_CFG_DIR="${COSMO_CFG_DIR:?set COSMO_CFG_DIR (subgraph URLs -> http://bench-sg:4200)}" +QUERY_FILE="${QUERY_FILE:?set QUERY_FILE}" +EXPECTED_BYTES="${EXPECTED_BYTES:-87599}" +NET=bench-net; SG=bench-sg; GWC=bench-gw +WORK="${WORK:-$(mktemp -d)}" + +cleanup(){ docker rm -f "$GWC" "$SG" >/dev/null 2>&1; } +cleanup +docker network rm "$NET" >/dev/null 2>&1; sleep 1; docker network create "$NET" >/dev/null 2>&1 + +docker run -d --name "$SG" --network "$NET" "$SUBGRAPHS_IMAGE" >/dev/null 2>&1 +for i in $(seq 1 60); do + docker run --rm --network "$NET" curlimages/curl:latest -fsS --max-time 1 -X POST http://$SG:4200/products -H 'content-type: application/json' -d '{"query":"{topProducts{upc}}"}' >/dev/null 2>&1 && break + sleep 0.5 +done + +BASE_HASH="" +FAIL=0 + +run_mode(){ + local mode="$1" dataflow="$2" schedule="$3" + docker rm -f "$GWC" >/dev/null 2>&1 + docker run -d --name "$GWC" --network "$NET" \ + -e LISTEN_ADDR=0.0.0.0:4000 -e LOG_LEVEL=info \ + -e TRACING_ENABLED=false -e METRICS_ENABLED=false -e METRICS_OTLP_ENABLED=false \ + -e GRAPHQL_METRICS_ENABLED=false -e PROMETHEUS_ENABLED=false -e ACCESS_LOGS_ENABLED=false \ + -e ENGINE_ENABLE_DATAFLOW="$dataflow" -e ENGINE_ENABLE_SCHEDULE_TREE="$schedule" \ + -e ROUTER_CONFIG_PATH=/etc/cosmo/config.json -e CONFIG_PATH=/etc/cosmo/config.yaml \ + -v "$COSMO_CFG_DIR:/etc/cosmo:ro" "$ROUTER_IMAGE" >/dev/null 2>&1 + + local EP="http://$GWC:4000/graphql" up=0 + for i in $(seq 1 120); do + docker run --rm --network "$NET" curlimages/curl:latest -fsS --max-time 3 -X POST "$EP" -H 'content-type: application/json' -d '{"query":"{__typename}"}' >/dev/null 2>&1 && { up=1; break; } + sleep 0.5 + done + [ "$up" = 1 ] || { echo "BYTEID FAIL [$mode]: router did not come up"; docker logs "$GWC" 2>&1 | tail -5; FAIL=1; return; } + + local logs; logs=$(docker logs "$GWC" 2>&1) + if [ "$dataflow" = "true" ] && ! echo "$logs" | grep -q "dataflow executor enabled"; then + echo "BYTEID FAIL [$mode]: ENGINE_ENABLE_DATAFLOW not plumbed through"; FAIL=1; return + fi + if [ "$schedule" = "true" ] && ! echo "$logs" | grep -q "schedule-tree planner enabled"; then + echo "BYTEID FAIL [$mode]: ENGINE_ENABLE_SCHEDULE_TREE not plumbed through"; FAIL=1; return + fi + + local outdir="$WORK/byteid_$mode" + rm -rf "$outdir"; mkdir -p "$outdir" + for i in $(seq 1 25); do + docker run --rm --network "$NET" -v "$QUERY_FILE:/q.json:ro" curlimages/curl:latest \ + -fsS --max-time 30 -X POST "$EP" -H 'content-type: application/json' --data-binary @/q.json \ + >"$outdir/seq_$i.json" 2>/dev/null + done + # 25 concurrent. Helper script: the redirect must live INSIDE the spawned + # shell, and BSD xargs rejects long inline -I{} commands. + cat > "$WORK/byteid_curl.sh" < $outdir/conc_\$1.json 2>/dev/null +HELPER + chmod +x "$WORK/byteid_curl.sh" + seq 1 25 | xargs -P 25 -n 1 "$WORK/byteid_curl.sh" + + local hashes bytes nfiles + hashes=$(shasum -a 256 "$outdir"/*.json | awk '{print $1}' | sort -u) + bytes=$(wc -c < "$outdir/seq_1.json" | tr -d ' ') + nfiles=$(ls "$outdir"/*.json | wc -l | tr -d ' ') + local nhashes; nhashes=$(echo "$hashes" | grep -c .) + if [ "$nhashes" != 1 ]; then + echo "BYTEID FAIL [$mode]: $nhashes distinct hashes within mode ($nfiles files)"; FAIL=1; return + fi + if [ "$bytes" != "$EXPECTED_BYTES" ]; then + echo "BYTEID FAIL [$mode]: byte length $bytes != $EXPECTED_BYTES"; FAIL=1; return + fi + if [ -z "$BASE_HASH" ]; then + BASE_HASH="$hashes" + elif [ "$hashes" != "$BASE_HASH" ]; then + echo "BYTEID FAIL [$mode]: hash differs from baseline"; FAIL=1; return + fi + echo "BYTEID OK [$mode]: $nfiles/$nfiles identical, sha256=${hashes:0:16}..., bytes=$bytes" +} + +run_mode baseline false false +run_mode dataflow true false +run_mode scheduler false true +run_mode both true true + +cleanup; docker network rm "$NET" >/dev/null 2>&1 +if [ "$FAIL" != 0 ]; then echo "BYTEID GATE: FAIL"; exit 1; fi +echo "BYTEID GATE: PASS (all 4 modes byte-identical, $EXPECTED_BYTES bytes)" diff --git a/router-tests/bench/engine-modes/k6.js b/router-tests/bench/engine-modes/k6.js new file mode 100644 index 0000000000..26a4f23782 --- /dev/null +++ b/router-tests/bench/engine-modes/k6.js @@ -0,0 +1,2579 @@ +import http from "k6/http"; +import { check } from "k6"; +import { Rate } from "k6/metrics"; +import { textSummary } from "https://jslib.k6.io/k6-summary/0.0.1/index.js"; +import { randomString } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js'; + +const endpoint = __ENV.GATEWAY_ENDPOINT || "http://0.0.0.0:4000/graphql"; +const mode = __ENV.MODE || "constant"; +const isConstant = mode === "constant"; +const vus = __ENV.BENCH_VUS ? parseInt(__ENV.BENCH_VUS) : isConstant ? 50 : 500; +const duration = __ENV.BENCH_OVER_TIME || "60s"; + +const successRate = new Rate("success_rate"); + +const summaryTrendStats = [ + "avg", + "min", + "med", + "max", + "p(90)", + "p(95)", + "p(99.9)", +]; + +export const options = isConstant + ? { + duration, + vus, + summaryTrendStats, + } + : { + scenarios: { + stress: { + executor: "ramping-vus", + startVUs: 0, + stages: [ + { duration: "5s", target: 50 }, + { duration: "40s", target: vus }, + { duration: "5s", target: 50 }, + ], + gracefulRampDown: "1s", + gracefulStop: "0s", + }, + }, + summaryTrendStats, + }; + +export function setup() { + for (let i = 0; i < 8; i++) { + sendGraphQLRequest(); + } +} + +export default function () { + makeGraphQLRequest(); +} + +export function handleSummary(data) { + return handleBenchmarkSummary(data, { vus, duration }); +} + +let printIdentifiersMap = {}; +let runIdentifiersMap = {}; + +function printOnce(identifier, ...args) { + if (printIdentifiersMap[identifier]) { + return; + } + + console.log(...args); + printIdentifiersMap[identifier] = true; +} + +function runOnce(identifier, cb) { + if (runIdentifiersMap[identifier]) { + return true; + } + + runIdentifiersMap[identifier] = true; + return cb(); +} + +const generateRandomID = () => { + // generate a random 10 character string + //return randomString(10, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz') + return "MyQuery" +} + +const graphqlRequest = (name) => ({ + payload: JSON.stringify({ + operationName: name, + query: `fragment User on User { + id + username + name + } + + fragment Review on Review { + id + body + } + + fragment Product on Product { + inStock + name + price + shippingEstimate + upc + weight + } + + query ${name} { + users { + ...User + reviews { + ...Review + product { + ...Product + reviews { + ...Review + author { + ...User + reviews { + ...Review + product { + ...Product + } + } + } + } + } + } + } + topProducts { + ...Product + reviews { + ...Review + author { + ...User + reviews { + ...Review + product { + ...Product + } + } + } + } + } + }`, + }), + params: { + headers: { + "Content-Type": "application/json", + }, + }, +}); + +function handleBenchmarkSummary(data, additionalContext = {}) { + const out = { + stdout: textSummary(data, { indent: " ", enableColors: true }), + }; + + if (__ENV.SUMMARY_PATH) { + out[`${__ENV.SUMMARY_PATH}/k6_summary.json`] = JSON.stringify( + Object.assign(data, additionalContext) + ); + out[`${__ENV.SUMMARY_PATH}/k6_summary.txt`] = textSummary(data, { + indent: " ", + enableColors: false, + }); + } + + return out; +} + +function sendGraphQLRequest() { + const gql = graphqlRequest(generateRandomID()); + const res = http.post( + endpoint, + gql.payload, + gql.params, + ); + + return res; +} + +function makeGraphQLRequest() { + const res = sendGraphQLRequest(); + const ok = check(res, { + "response code was 200": (res) => res.status == 200, + "no graphql errors": (resp) => { + let has_errors = !!resp.body && resp.body.includes(`"errors"`); + if (has_errors && __ENV.PRINT_ONCE) { + printOnce( + "graphql_errors", + `‼️ Got GraphQL errors, here's a sample:`, + res.json.errors + ); + } + + return !has_errors; + }, + "valid response structure": (resp) => { + return runOnce("valid response structure", () => { + const json = resp.json(); + + let isValid = checkResponseStructure(json); + + if (!isValid && __ENV.PRINT_ONCE) { + printOnce( + "response_strcuture", + `‼️ Got invalid structure, here's a sample:`, + res.body + ); + } + + return isValid; + }); + }, + }); + + successRate.add(ok); +} + +function checkResponseStructure(x) { + function checkRecursive(obj, structure) { + if (obj == null) { + return false; + } + for (var key in structure) { + if ( + !obj.hasOwnProperty(key) || + typeof obj[key] !== typeof structure[key] + ) { + return false; + } + if (typeof structure[key] === "object" && structure[key] !== null) { + if (!checkRecursive(obj[key], structure[key])) { + return false; + } + } + } + return true; + } + + const expectedStructure = { + data: { + users: [ + { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "3", + body: "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "4", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "3", + body: "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "4", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + { + id: "2", + username: "dotansimha", + name: "Dotan Simha", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "3", + body: "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "4", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "3", + body: "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "4", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + { + id: "3", + username: "kamilkisiela", + name: "Kamil Kisiela", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "3", + body: "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "4", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "3", + body: "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "4", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + { + id: "4", + username: "ardatan", + name: "Arda Tanrikulu", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "3", + body: "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "4", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "3", + body: "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "4", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + { + id: "5", + username: "gilgardosh", + name: "Gil Gardosh", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "3", + body: "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "4", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "3", + body: "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "4", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + { + id: "6", + username: "laurin", + name: "Laurin Quast", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "3", + body: "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "4", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "3", + body: "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "4", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + }, + ], + }, + ], + topProducts: [ + { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "3", + body: "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "4", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + { + inStock: false, + name: "Couch", + price: 1299, + shippingEstimate: null, + upc: "2", + weight: 1000, + reviews: [ + { + id: "5", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "6", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "7", + body: "sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "8", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + { + inStock: false, + name: "Glass", + price: 15, + shippingEstimate: null, + upc: "3", + weight: 20, + reviews: [ + { + id: "9", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + { + inStock: false, + name: "Chair", + price: 499, + shippingEstimate: null, + upc: "4", + weight: 100, + reviews: [ + { + id: "10", + body: "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + { + id: "11", + body: "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.", + author: { + id: "1", + username: "urigo", + name: "Uri Goldshtein", + reviews: [ + { + id: "1", + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + { + id: "2", + body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugi", + product: { + inStock: true, + name: "Table", + price: 899, + shippingEstimate: null, + upc: "1", + weight: 100, + }, + }, + ], + }, + }, + ], + }, + { + inStock: true, + name: "TV", + price: 1299, + shippingEstimate: null, + upc: "5", + weight: 1000, + reviews: [], + }, + ], + }, + }; + return checkRecursive(x, expectedStructure); +} diff --git a/router-tests/bench/engine-modes/lat-proxy/Dockerfile b/router-tests/bench/engine-modes/lat-proxy/Dockerfile new file mode 100644 index 0000000000..28fc255391 --- /dev/null +++ b/router-tests/bench/engine-modes/lat-proxy/Dockerfile @@ -0,0 +1,8 @@ +FROM golang:1.25-alpine AS build +WORKDIR /src +COPY main.go . +RUN go mod init lat-proxy && CGO_ENABLED=0 go build -ldflags '-s -w' -o /lat-proxy . + +FROM alpine:3.20 +COPY --from=build /lat-proxy /lat-proxy +ENTRYPOINT ["/lat-proxy"] diff --git a/router-tests/bench/engine-modes/lat-proxy/main.go b/router-tests/bench/engine-modes/lat-proxy/main.go new file mode 100644 index 0000000000..17c8288e80 --- /dev/null +++ b/router-tests/bench/engine-modes/lat-proxy/main.go @@ -0,0 +1,74 @@ +// lat-proxy injects a per-subgraph artificial latency in front of a single +// upstream that serves all subgraphs on distinct path prefixes (the hive +// gateways-benchmark subgraph container: /accounts /products /reviews +// /inventory). The delay is applied to the RESPONSE (after the upstream call +// returns), matching the semantics of netem egress delay on the subgraph +// container used by the uniform benchmark. +// +// Env: +// +// UPSTREAM upstream base URL, e.g. http://bench-sg:4200 +// DELAYS per-path-prefix delays, e.g. "accounts=20,products=20,reviews=20,inventory=150" +// LISTEN listen address (default :8080) +package main + +import ( + "log" + "net/http" + "net/http/httputil" + "net/url" + "os" + "strconv" + "strings" + "time" +) + +func main() { + upstream := os.Getenv("UPSTREAM") + if upstream == "" { + log.Fatal("UPSTREAM is required") + } + target, err := url.Parse(upstream) + if err != nil { + log.Fatalf("invalid UPSTREAM: %v", err) + } + + delays := map[string]time.Duration{} + for pair := range strings.SplitSeq(os.Getenv("DELAYS"), ",") { + name, ms, ok := strings.Cut(strings.TrimSpace(pair), "=") + if !ok || name == "" { + continue + } + n, err := strconv.Atoi(ms) + if err != nil { + log.Fatalf("invalid delay %q: %v", pair, err) + } + delays[name] = time.Duration(n) * time.Millisecond + } + + proxy := httputil.NewSingleHostReverseProxy(target) + // The benchmark fans out aggressively; default transports throttle at + // 2 idle conns per host, which fabricates failures under load. + proxy.Transport = &http.Transport{ + MaxIdleConns: 4096, + MaxIdleConnsPerHost: 4096, + IdleConnTimeout: 90 * time.Second, + } + proxy.ModifyResponse = func(resp *http.Response) error { + seg := strings.TrimPrefix(resp.Request.URL.Path, "/") + if i := strings.IndexByte(seg, '/'); i >= 0 { + seg = seg[:i] + } + if d, ok := delays[seg]; ok && d > 0 { + time.Sleep(d) + } + return nil + } + + listen := os.Getenv("LISTEN") + if listen == "" { + listen = ":8080" + } + log.Printf("lat-proxy listening on %s -> %s, delays=%v", listen, upstream, delays) + log.Fatal(http.ListenAndServe(listen, proxy)) +} diff --git a/router-tests/bench/engine-modes/skew_bench.sh b/router-tests/bench/engine-modes/skew_bench.sh new file mode 100755 index 0000000000..6472ba8b17 --- /dev/null +++ b/router-tests/bench/engine-modes/skew_bench.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# Skewed per-subgraph latency benchmark for ONE cosmo engine mode: the lat-proxy +# injects a DIFFERENT delay per subgraph path, then forwards to the subgraph +# container. This exposes the per-wave-barrier slack that uniform latency hides +# — the regime where the dataflow executor and the schedule-tree scheduler earn +# their keep. +# +# Usage: DELAYS="accounts=20,products=20,reviews=20,inventory=150" skew_bench.sh +# Env: ROUTER_IMAGE SUBGRAPHS_IMAGE LAT_PROXY_IMAGE COSMO_CFG_DIR (subgraph +# URLs -> http://lat-proxy:8080) QUERY_FILE EXPECTED_BYTES LABEL +# DATAFLOW SCHEDULE_TREE REP VUS DUR RES +set -uo pipefail +CPUS="$1"; MEMG="$2"; REP="${REP:-1}"; MEM="${MEMG}g" +VUS="${VUS:-1}"; DUR="${DUR:-20s}"; DELAYS="${DELAYS:-accounts=20,products=20,reviews=20,inventory=150}" +LABEL="${LABEL:-cosmo-baseline}" +ROUTER_IMAGE="${ROUTER_IMAGE:-bench-cosmo:local}" +SUBGRAPHS_IMAGE="${SUBGRAPHS_IMAGE:-bench-subgraphs:latest}" +LAT_PROXY_IMAGE="${LAT_PROXY_IMAGE:-lat-proxy:local}" +COSMO_CFG_DIR="${COSMO_CFG_DIR:?set COSMO_CFG_DIR to the dir with config.json + config.yaml (subgraph URLs -> http://lat-proxy:8080)}" +QUERY_FILE="${QUERY_FILE:?set QUERY_FILE to the federated query JSON body}" +EXPECTED_BYTES="${EXPECTED_BYTES:-87599}" +K6JS="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/k6.js" +RES="${RES:?set RES to the results jsonl path}" +GOMEM_MIB="$(( MEMG * 1024 * 80 / 100 ))MiB" +CPUSET="0-$((CPUS-1))"; [ "$CPUS" = "1" ] && CPUSET="0" +NET=bench-net; SG=bench-sg; PX=lat-proxy; GWC=bench-gw +mkdir -p "$(dirname "$RES")" +cleanup(){ pkill -9 -f "docker stats" >/dev/null 2>&1; docker rm -f "$GWC" "$SG" "$PX" bench-k6 >/dev/null 2>&1; } +cleanup +for i in $(seq 1 30); do docker ps -aq --filter "name=$GWC" --filter "name=$SG" --filter "name=$PX" | grep -q . || break; sleep 0.5; done +docker network rm "$NET" >/dev/null 2>&1; sleep 1; docker network create "$NET" >/dev/null 2>&1 + +docker run -d --name "$SG" --network "$NET" "$SUBGRAPHS_IMAGE" >/dev/null 2>&1 +for i in $(seq 1 60); do docker run --rm --network "$NET" curlimages/curl:latest -fsS --max-time 1 -X POST http://$SG:4200/products -H 'content-type: application/json' -d '{"query":"{topProducts{upc}}"}' >/dev/null 2>&1 && break; sleep 0.5; done +# latency proxy in front of the subgraphs +docker run -d --name "$PX" --network "$NET" -e UPSTREAM="http://$SG:4200" -e DELAYS="$DELAYS" "$LAT_PROXY_IMAGE" >/dev/null 2>&1 +for i in $(seq 1 30); do docker run --rm --network "$NET" curlimages/curl:latest -fsS --max-time 2 -X POST http://$PX:8080/products -H 'content-type: application/json' -d '{"query":"{topProducts{upc}}"}' >/dev/null 2>&1 && break; sleep 0.5; done + +docker run -d --name "$GWC" --network "$NET" --cpuset-cpus="$CPUSET" --memory="$MEM" \ + -e GOMAXPROCS="$CPUS" -e GOMEMLIMIT="$GOMEM_MIB" -e LISTEN_ADDR=0.0.0.0:4000 -e LOG_LEVEL=fatal \ + -e TRACING_ENABLED=false -e METRICS_ENABLED=false -e METRICS_OTLP_ENABLED=false \ + -e GRAPHQL_METRICS_ENABLED=false -e PROMETHEUS_ENABLED=false -e ACCESS_LOGS_ENABLED=false \ + -e ENGINE_ENABLE_DATAFLOW="${DATAFLOW:-false}" -e ENGINE_ENABLE_SCHEDULE_TREE="${SCHEDULE_TREE:-false}" \ + -e ROUTER_CONFIG_PATH=/etc/cosmo/config.json -e CONFIG_PATH=/etc/cosmo/config.yaml \ + -v "$COSMO_CFG_DIR:/etc/cosmo:ro" "$ROUTER_IMAGE" >/dev/null 2>&1 + +EP="http://$GWC:4000/graphql" +up=0 +for i in $(seq 1 120); do docker run --rm --network "$NET" curlimages/curl:latest -fsS --max-time 3 -X POST "$EP" -H 'content-type: application/json' -d '{"query":"{__typename}"}' >/dev/null 2>&1 && { up=1; break; }; docker ps --filter "name=$GWC" --filter status=running -q | grep -q . || { sleep 0.5; continue; }; sleep 0.5; done +if [ "$up" != 1 ]; then echo "{\"rep\":$REP,\"label\":\"$LABEL\",\"delays\":\"$DELAYS\",\"error\":\"no up\"}" | tee -a "$RES"; cleanup; exit 1; fi +ready=0 +for i in $(seq 1 30); do rb=$(docker run --rm --network "$NET" -v "$QUERY_FILE:/q.json:ro" curlimages/curl:latest -fsS --max-time 20 -X POST "$EP" -H 'content-type: application/json' --data-binary @/q.json 2>/dev/null | wc -c | tr -d ' '); [ "${rb:-0}" -ge $(( EXPECTED_BYTES * 99 / 100 )) ] && { ready=1; break; }; sleep 0.5; done +if [ "$ready" != 1 ]; then echo "{\"rep\":$REP,\"label\":\"$LABEL\",\"delays\":\"$DELAYS\",\"error\":\"not federating\"}" | tee -a "$RES"; cleanup; exit 1; fi +VB=$(docker run --rm --network "$NET" -v "$QUERY_FILE:/q.json:ro" curlimages/curl:latest -fsS --max-time 20 -X POST "$EP" -H 'content-type: application/json' --data-binary @/q.json 2>/dev/null | wc -c | tr -d ' ') + +STATF=$(mktemp); : > "$STATF" +docker stats --format '{{.CPUPerc}}|{{.MemUsage}}' "$GWC" >>"$STATF" 2>/dev/null & SAMP=$! + +K6OUT=$(mktemp -d); rm -f "$K6OUT/k6_summary.json" +docker run --rm --network "$NET" -v "$K6JS:/k6.js:ro" -v "$K6OUT:/out" \ + -e GATEWAY_ENDPOINT="$EP" -e MODE=constant -e BENCH_VUS="$VUS" -e BENCH_OVER_TIME="$DUR" -e SUMMARY_PATH=/out -e K6_SETUP_TIMEOUT=600s \ + grafana/k6:latest run /k6.js >/dev/null 2>&1 +kill -9 "$SAMP" >/dev/null 2>&1; wait "$SAMP" 2>/dev/null +J="$K6OUT/k6_summary.json" +RPS=$(jq -r '.metrics.http_reqs.values.rate|floor' "$J" 2>/dev/null); SUCC=$(jq -r '.metrics.success_rate.values.rate' "$J" 2>/dev/null) +MIN=$(jq -r '.metrics.http_req_duration.values.min' "$J" 2>/dev/null); MED=$(jq -r '.metrics.http_req_duration.values.med' "$J" 2>/dev/null) +P90=$(jq -r '.metrics.http_req_duration.values["p(90)"]' "$J" 2>/dev/null); P999=$(jq -r '.metrics.http_req_duration.values["p(99.9)"]' "$J" 2>/dev/null) +P95=$(jq -r '.metrics.http_req_duration.values["p(95)"]' "$J" 2>/dev/null) +read CPUAVG CPUMAX MEMMAX <<<"$(tr -d '\r' < "$STATF" | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' | awk -F'|' '{gsub(/%/,"",$1);c=$1+0;if(c>cm)cm=c;cs+=c;n++;split($2,a,"/");m=a[1];gsub(/[^0-9.A-Za-z]/,"",m);v=m+0;if(m~/GiB/)v*=1024;if(m~/KiB/)v/=1024;if(v>mm)mm=v} END{if(n)printf "%.0f %.0f %.0f",cs/n,cm,mm;else print "0 0 0"}')" +rm -rf "$STATF" "$K6OUT" +echo "{\"rep\":$REP,\"label\":\"$LABEL\",\"dataflow\":\"${DATAFLOW:-false}\",\"schedule_tree\":\"${SCHEDULE_TREE:-false}\",\"delays\":\"$DELAYS\",\"vus\":$VUS,\"rps\":${RPS:-0},\"success\":${SUCC:-0},\"min_ms\":${MIN:-0},\"med_ms\":${MED:-0},\"p90_ms\":${P90:-0},\"p95_ms\":${P95:-0},\"p999_ms\":${P999:-0},\"cpu_avg_pct\":${CPUAVG:-0},\"cpu_max_pct\":${CPUMAX:-0},\"mem_max_mib\":${MEMMAX:-0},\"valid_bytes\":${VB:-0}}" | tee -a "$RES" +cleanup diff --git a/router-tests/bench/engine-modes/skew_matrix.sh b/router-tests/bench/engine-modes/skew_matrix.sh new file mode 100755 index 0000000000..9570bb53ba --- /dev/null +++ b/router-tests/bench/engine-modes/skew_matrix.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# Skew matrix: 3 cosmo engine modes x {1 VU, 64 VU} x 3 reps with one slow +# subgraph (inventory=150ms vs 20ms) — the regime where the executors differ. +# Modes interleaved per cell; plus 2 cosmo-both-SMOKE footnote rows asserting +# the safe degradation of running BOTH flags (nested schedule-tree plans make +# the dataflow executor fall back; expect ~cosmo-scheduler numbers). +set -uo pipefail +D="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +RES="${RES:?set RES to the results jsonl path}" +: > "$RES" +CPUS="${CPUS:-4}"; MEMG="${MEMG:-2}" +DELAYS="${DELAYS:-accounts=20,products=20,reviews=20,inventory=150}" +# run