TL;DR
- Distinguish valid JSON syntax from data that satisfies an application's schema and permissions.
- Explain objects, arrays, strings, numbers, booleans and null with concrete API examples.
- Test missing fields, unexpected properties, numeric precision and serialization behavior instead of trusting a successful parse.
- Preserve a clear boundary between parsing, validation, authorization and the operation that changes data.
1. What is JSON, and how does it differ from a JavaScript object?
JSON is a text format for exchanging structured data. A JavaScript object is a runtime value. Parsing translates suitable text into a runtime value; serialization produces text from a supported value. Confusing those two representations leads to bugs at API boundaries.
RFC 8259 defines JSON values as objects, arrays, strings, numbers, booleans or null. Object member names are strings. Standard JSON does not provide comments, trailing commas, functions or an undefined literal. Arrays preserve a sequence; portable object handling should not depend on member order.
Use a small example in an interview. A job record might contain an identifier string, a title string and a numeric priority. The text travels over the connection; the receiving program must still decide whether those values are acceptable for that operation.
The phrase “it is JSON” answers a format question. It does not prove that the sender is trusted, that the fields are meaningful or that a database update should proceed.
2. Does JSON.parse validate an API request?
It validates whether the text can be parsed as JSON, not whether it matches your application's contract. MDN's JSON.parse reference describes parsing into the corresponding JavaScript value and throwing a SyntaxError for malformed JSON.
For example, both null and an empty array are valid JSON documents. Neither is necessarily an acceptable job-update request. A parser can successfully return an object whose title is missing or whose priority is the string “urgent,” even when the application expects an integer.
Describe two separate failure paths: malformed text and a well-formed but unacceptable payload. A client benefits from a stable explanation of which contract it violated. The server also benefits from avoiding an accidental crash caused by reading a property from null. In backend API design interviews, you may be asked how you would structure the error response for each path.
Do not use evaluation of source code as a substitute for a JSON parser. The task is to interpret a data format, not execute a submitted program.
3. Can you write a small parser with explicit validation?
This original JavaScript exercise accepts one deliberately narrow job-update shape. It returns a fresh object containing only approved fields:
function parseJobUpdate(text) {
if (typeof text !== "string") {
throw new TypeError("Expected JSON text");
}
const value = JSON.parse(text);
if (value === null || typeof value !== "object" ||
Array.isArray(value)) {
throw new TypeError("Expected an object");
}
const allowed = ["id", "title", "priority"];
if (Object.keys(value).some(key => !allowed.includes(key))) {
throw new TypeError("Unexpected field");
}
if (typeof value.id !== "string" ||
!/^job_[a-z0-9]+$/.test(value.id)) {
throw new TypeError("Invalid job ID");
}
if (typeof value.title !== "string" ||
value.title.trim().length < 1 ||
value.title.trim().length > 120) {
throw new TypeError("Invalid title");
}
if (!Number.isInteger(value.priority) ||
value.priority < 1 || value.priority > 3) {
throw new TypeError("Invalid priority");
}
return {
id: value.id,
title: value.title.trim(),
priority: value.priority
};
}The limits are assumptions for this exercise, not universal JSON rules. Explain why each exists and what the product team would need to decide differently for a real endpoint.
The function does not enforce a request-body byte limit, authenticate the caller or confirm ownership of the job. Those responsibilities belong around it in the service. It also uses JavaScript string length for the title; a product promising a particular human-visible character count needs an explicitly chosen counting rule.
4. Which test cases would you write?
Begin with the accepted request {"id":"job_a1","title":" Review draft ","priority":2}. Expect a trimmed title and the same identifier and priority. Then test each boundary independently:
| Input change | Expected result in this exercise | Reason |
|---|---|---|
| Document is null or an array | Reject | Wrong top-level shape |
| Title is missing or only spaces | Reject | No usable title |
| Title contains 120 ordinary letters | Accept | Inclusive upper boundary |
| Title contains 121 ordinary letters | Reject | Exceeds the chosen boundary |
| Priority is 1 or 3 | Accept | Both allowed endpoints |
| Priority is 0, 4, fractional or a string | Reject | Wrong range or type |
| An extra ownership field appears | Reject | Not part of the accepted shape |
| Text has a trailing comma | Parse failure | Malformed standard JSON |
Test that an error does not perform the update. In a service-level test, the database-writing function should remain uncalled for invalid input. A successful validation test alone does not prove that the endpoint observes that rule.
Add an authorization test separately: a valid request for a job belonging to another account must still fail. That test addresses a different concern from parsing, one that security engineer interviews often frame as broken access control.
5. Why can large JSON numbers be a problem in JavaScript?
The transmitted digits and the receiving runtime's numeric representation are different concerns. MDN notes that precision can already be lost by the time a parsed number reaches a reviver.
For an opaque identifier, agree on a string representation rather than assuming every participant can preserve an arbitrarily large integer. In an interview, compare the incoming text 9007199254740993 with its JavaScript parsed value and explain why an identifier should not silently change.
Make the wire contract explicit for quantities too. If an amount uses integer minor units, state the unit, supported range and rounding policy. A field named “amount” without those decisions leaves important behavior undefined. This article's priority field avoids that ambiguity by accepting only three small integer values.
Do not fix an identifier by converting an already-rounded number back to a string. At that point the original digits may be gone.
6. What happens to undefined, BigInt and circular references?
MDN's JSON.stringify documentation describes different behavior for unsupported values. An undefined object property is omitted, while an undefined array entry becomes null. Serializing a BigInt normally throws unless a deliberate serialization method is supplied, and circular references also cause an error.
Use these behaviors to explain why a generic stringify-and-parse round trip is not a universal cloning method. A JavaScript object containing dates, omitted fields or unsupported values may not retain the same meaning after that round trip. Keep that limitation in mind when frontend engineer interview questions ask you to implement a deep clone.
For an API, define the representation you intend. If a date is transmitted as text, specify its format and interpretation. If a field is optional, explain whether omission means “leave unchanged” and null means “clear it,” or whether the endpoint uses a different rule.
A small contract decision can prevent a major update bug. A client should not erase a saved value merely because a serializer omitted an undefined property.
7. What should happen with duplicate or unexpected keys?
The JSON standard recommends unique object names and describes differing receiver behavior when names repeat. Avoid duplicate keys in an interoperable contract. JavaScript's standard parser does not provide this exercise with a duplicate-key rejection step; repeated names can collapse before the validation function sees the result.
If an endpoint requires strict duplicate rejection, enforce it with a parser or validation layer that retains that information. Do not claim that the Object.keys check above catches duplicate occurrences in the original text. It catches unexpected names in the parsed object.
For larger contracts, JSON Schema's object guidance provides tools such as required properties and control over additional properties. Defining a property does not by itself make it required. Choose strictness deliberately: rejecting unexpected fields can catch errors, while schema evolution may require a compatible extension policy.
Explain the policy to clients and test old and new versions against it. Quietly accepting a typo in a field name can be just as confusing as rejecting a documented optional field.
8. How would you protect the endpoint around the parser?
OWASP's REST security guidance covers access control, content-type handling and input validation at service boundaries. Apply those concerns before treating a parsed record as an authorized command.
For the job exercise, describe the full path: enforce a request size limit, accept the intended media type, parse and validate the body, authenticate the caller, verify access to the specific job, perform the allowed update and return a stable response. The exact ordering can reflect the framework, but every boundary must be accounted for.
When practicing, separate tests by the failure they demonstrate. A malformed document, an unknown field, an inaccessible job and a database failure should not all be described as “bad JSON.” Precise explanations show that you understand both the format and the application that depends on it.