Validating Response Bodies (JSON)

Avatar of Hemanta SundarayHemanta Sundaray

Every call to response.json in this course so far has returned unknown. This means TypeScript has no idea what shape the data is, so it can’t warn you if you access a property that doesn’t exist or if the API changes its response format.

HttpClientResponse.schemaBodyJson() solves this by validating the response body against a Schema. If the response matches, you get a fully typed value. If it doesn’t, you get a typed SchemaError.

http.ts
import {
FetchHttpClient,
HttpClient,
HttpClientRequest,
HttpClientResponse,
} from "effect/unstable/http";
import { Effect, Schema } from "effect";
const User = Schema.Struct({
id: Schema.Number,
firstName: Schema.String,
lastName: Schema.String,
email: Schema.String,
age: Schema.Number,
});
function fetchUser(userId: number) {
return Effect.gen(function* () {
const client = yield* HttpClient.HttpClient;
const request = HttpClientRequest.get(
`https://dummyjson.com/users/${userId}`,
);
const response = yield* client.execute(request);
// Validate the response body against the User schema
const user = yield* HttpClientResponse.schemaBodyJson(User)(response);
return user;
}).pipe(Effect.provide(FetchHttpClient.layer));
}
// Test it
Effect.runPromise(fetchUser(1)).then((user) => {
// user is fully typed: { id: number, firstName: string, ... }
console.log(`${user.firstName} ${user.lastName}, age ${user.age}`);
console.log(`Email: ${user.email}`);
});

Output:

Terminal
Emily Johnson, age 29
Email: emily.johnson@x.dummyjson.com

schemaBodyJson is a curried function. You first pass the schema, then the response:

Terminal
HttpClientResponse.schemaBodyJson(User)(response);
// ^^^^ ^^^^^^^^
// schema response

In the example above, the return type is now { id: number; firstName: string; lastName: string; email: string; age: number } instead of unknown. TypeScript knows exactly what you’re working with.

Under the hood, schemaBodyJson() calls response.json to parse the body, then runs the schema validation. If validation fails, it produces a SchemaError in the error channel.

Note that SchemaError is a schema validation failure, not an HTTP failure. This means it’s a separate error type from HttpClientError, and you can catch them independently.

By default, schema validation strips unknown properties. The dummyJSON API returns many more fields (like phone, image, address), but our schema only declares five fields, so those extras are silently dropped. This is a good thing. Your code only depends on the fields you’ve explicitly declared, making it resilient to upstream API changes.

Sign in to save progress

Stay in the loop

Get notified when new chapters are added and when this course is complete.