31. Design APIs for a nearby-friends and nearby-places service.
Define APIs for updating location, querying nearby entities, controlling privacy, paginating results, setting freshness requirements, and handling authorization, abuse, and failures.
At a high level, I would place four location APIs behind an API Gateway and Rate Limiter. The client first gets a JWT access token from the Identity Provider. It can then update its location, find nearby friends, find nearby places, or change location-sharing privacy. The Nearby API Service checks privacy rules and queries separate geo indexes for users and places. Results support pagination and freshness requirements. Invalid tokens return 401, excessive traffic returns 429, and storage or policy problems return clear failures. The main trade-off is better privacy and control at the cost of extra service calls.
The goal is to provide useful nearby results without exposing private location data. The main challenge is combining fresh geo searches with privacy, authorization, and abuse protection. I would explain the design by following each request through the approved diagram.
- Which clients and core use cases must the API support?
- What authentication, authorization, and data-validation rules should I assume?
- What scale, error handling, idempotency, and versioning requirements matter?
I would begin by placing every business API behind the API Gateway and Rate Limiter.
The Mobile or Web Client performs an OAuth2 login with the Identity Provider or Auth Service. The identity service returns a JWT access token. A JWT is a signed token that represents the authenticated user.
The client sends that token as a bearer token on later API calls. The gateway checks the token before forwarding each request. A missing, invalid, or expired token returns 401. A caller that exceeds the allowed request rate receives 429.
This edge layer keeps authentication and abuse controls outside the core location logic.
The client sends PUT /v1/me/location with {lat, lon, accuracy_m, timestamp}.
The gateway authenticates the request and forwards it to the Nearby API Service. The service checks the sharing policy with the Privacy and Relationship Policy Service. That service owns the friend graph, sharing settings, and block list.
After receiving the policy decision, the Nearby API Service upserts the location into the User Location Store and updates its geo index. Upsert means creating the record when missing or updating the existing record.
The store returns write success. The Nearby API Service then returns 200 OK or 202 Accepted through the gateway. The gateway sends the location update response back to the client.
The client calls GET /v1/nearby/friends?lat&lon&radius_m&limit&page_token&fresh_within_s.
The gateway authenticates the request and sends it to the Nearby API Service. The service first asks the Privacy and Relationship Policy Service for visible friends and block rules. The policy service returns the allowed friend IDs.
The Nearby API Service then sends a geo search to the User Location Store and Geo Index. The search applies the fresh_within_s requirement so old locations are not treated as current.
The store returns friend candidates with distance and last_updated_at. The service filters those candidates using the allowed friend IDs.
The response returns through the gateway as 200 with {items, next_page_token}. The client sends the returned token when requesting the next page.
The client calls GET /v1/nearby/places?lat&lon&radius_m&category&limit&page_token&fresh_within_s.
The gateway authenticates the request and forwards it to the Nearby API Service. The service sends a geo search to the Places Catalog and Places Geo Index.
That component returns place candidates with distance and metadata. The optional category value narrows the result set. The limit and page_token values keep each response bounded.
The Nearby API Service returns 200 with {items, next_page_token} through the gateway. The gateway then sends the nearby places response to the client.
The client sends PUT /v1/me/privacy/location-sharing with one of {friends_only | nobody | custom}.
The gateway authenticates the request and forwards it to the Nearby API Service. The service sends the update to the Privacy and Relationship Policy Service.
That policy service stores the new setting and returns update success. The Nearby API Service returns 200 OK through the gateway, and the gateway sends the privacy update response to the client.
The key decision is that privacy logic belongs to one policy service. The geo indexes only store and search location data.
The service returns 400 when request parameters are invalid. It returns 403 when privacy policy hides or blocks the requested result. It returns 503 when the geo store is unavailable.
The diagram also allows partial or empty results when the requested freshness cannot be met. This avoids presenting stale location data as current.
Every error or partial response returns through the gateway to the client. Logging remains separate from the business response path.
The gateway sends request metrics, authentication failures, and rate-limit events to Observability and Audit Logs. The Nearby API Service sends API metrics, errors, and privacy changes.
The benefit is clear responsibility. The gateway protects entry, the policy service owns privacy, and each geo index owns its search data.
The downside is additional network calls. A nearby-friends request may need both a policy lookup and a geo lookup. We accept that extra latency because correct privacy filtering is more important than the simplest possible request path.
The benefit is that each component has one clear job. The gateway checks JWT tokens and limits abusive traffic. The policy service controls sharing rules and blocked relationships. Separate geo indexes make user and place searches easier to manage. Pagination with limit and page_token prevents very large responses. The fresh_within_s value helps avoid stale locations. The downside is extra latency because one request may call several services. These calls also create more failure points. Returning partial or empty results protects freshness, but users may see fewer matches. Rate limiting reduces abuse, but strict limits can also affect valid users. This design is safer, but it needs careful monitoring. We accept the added complexity because location privacy and predictable failures are essential.
Interviewers use this question to test API design judgment rather than memorized endpoints. They want to see clear boundaries, correct request and response directions, and sensible HTTP behavior. They also check whether authentication, privacy authorization, pagination, freshness, and rate limiting are handled separately. Strong answers explain data ownership, failure behavior, and trade-offs without adding unnecessary infrastructure or making unsupported guarantees.







