Skip to content

feat(server): Add request context support#522

Open
dustinbyrne wants to merge 2 commits into
mainfrom
feat/server-request-context
Open

feat(server): Add request context support#522
dustinbyrne wants to merge 2 commits into
mainfrom
feat/server-request-context

Conversation

@dustinbyrne
Copy link
Copy Markdown
Contributor

💡 Motivation and Context

Server-side SDK users handling frontend requests need a safe way to carry PostHog frontend tracing context into backend captures. This adds request-scoped context support for posthog-server, so captures and exception captures can inherit frontend distinct/session metadata while still preserving explicit SDK call overrides.

💚 How did you test it?

  • ./gradlew :posthog-server:test --tests "com.posthog.server.PostHogRequestContextTest" --tests "com.posthog.server.PostHogEvaluateFlagsTest"
  • make checkFormat
  • ./gradlew :posthog-server:test
  • git diff --check
  • make api

📝 Checklist

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed.
  • No breaking change or entry added to the changelog.

If releasing new changes

  • Added a changeset file (.changeset/request-context-server.md)

@dustinbyrne dustinbyrne force-pushed the feat/server-request-context branch from ec3bde4 to f6c2cdb Compare May 26, 2026 20:29
@dustinbyrne dustinbyrne marked this pull request as ready for review May 26, 2026 20:30
@dustinbyrne dustinbyrne requested a review from a team as a code owner May 26, 2026 20:30
@dustinbyrne dustinbyrne changed the title Add server request context support feat(server): Add request context support May 26, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 26, 2026

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
posthog-server/src/test/java/com/posthog/server/PostHogEvaluateFlagsTest.kt:235-299
**Duplicate tests should be parameterized**

`evaluateFlags uses request context distinctId when omitted` and `evaluateFlags uses request context distinctId when null` are structurally identical — the only difference is calling `postHog.evaluateFlags()` vs `postHog.evaluateFlags(null)`. Per the team's preference for parameterized tests, these two cases should be collapsed into a single `@ParameterizedTest` (e.g. using a boolean parameter or a supplier for the call-under-test).

Reviews (1): Last reviewed commit: "fix: allow nullable request context dist..." | Re-trigger Greptile

Comment on lines +235 to +299
@Test
fun `evaluateFlags uses request context distinctId when omitted`() {
val mockServer = MockWebServer()
mockServer.enqueue(jsonResponse(createFlagsResponse("a", enabled = true)))
mockServer.start()

var postHog: PostHogInterface? = null
try {
postHog =
PostHog.with(
PostHogConfig.builder(TEST_API_KEY)
.host(mockServer.url("/").toString())
.build(),
)

val snapshot =
PostHogRequestContext.withContext(PostHogRequestContextData(distinctId = "context-user")) {
postHog.evaluateFlags()
}

assertEquals("context-user", snapshot.distinctId)
assertTrue(snapshot.isEnabled("a"))

val request = mockServer.takeRequest(2, TimeUnit.SECONDS)
assertNotNull(request)
val body = request.body.unGzip()
assertTrue(body.contains("\"distinct_id\":\"context-user\""), "expected context distinctId in request body, got: $body")
} finally {
postHog?.close()
mockServer.shutdown()
}
}

@Test
fun `evaluateFlags uses request context distinctId when null`() {
val mockServer = MockWebServer()
mockServer.enqueue(jsonResponse(createFlagsResponse("a", enabled = true)))
mockServer.start()

var postHog: PostHogInterface? = null
try {
postHog =
PostHog.with(
PostHogConfig.builder(TEST_API_KEY)
.host(mockServer.url("/").toString())
.build(),
)

val snapshot =
PostHogRequestContext.withContext(PostHogRequestContextData(distinctId = "context-user")) {
postHog.evaluateFlags(null)
}

assertEquals("context-user", snapshot.distinctId)
assertTrue(snapshot.isEnabled("a"))

val request = mockServer.takeRequest(2, TimeUnit.SECONDS)
assertNotNull(request)
val body = request.body.unGzip()
assertTrue(body.contains("\"distinct_id\":\"context-user\""), "expected context distinctId in request body, got: $body")
} finally {
postHog?.close()
mockServer.shutdown()
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Duplicate tests should be parameterized

evaluateFlags uses request context distinctId when omitted and evaluateFlags uses request context distinctId when null are structurally identical — the only difference is calling postHog.evaluateFlags() vs postHog.evaluateFlags(null). Per the team's preference for parameterized tests, these two cases should be collapsed into a single @ParameterizedTest (e.g. using a boolean parameter or a supplier for the call-under-test).

Prompt To Fix With AI
This is a comment left during a code review.
Path: posthog-server/src/test/java/com/posthog/server/PostHogEvaluateFlagsTest.kt
Line: 235-299

Comment:
**Duplicate tests should be parameterized**

`evaluateFlags uses request context distinctId when omitted` and `evaluateFlags uses request context distinctId when null` are structurally identical — the only difference is calling `postHog.evaluateFlags()` vs `postHog.evaluateFlags(null)`. Per the team's preference for parameterized tests, these two cases should be collapsed into a single `@ParameterizedTest` (e.g. using a boolean parameter or a supplier for the call-under-test).

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants