Search
30 results for “api”
Search results
What does FastAPI provide that Flask does not, and what's the trade-off?
FastAPI is async-first (built on ASGI, not WSGI) and uses Python type hints to automatically generate request validation, serialization, and interactive OpenAPI documentation, a type-annotated function signature becomes both the API contract and its enforcement, with no separate schema to maintain by hand. The trade-off is that FastAPI assumes an async-first mental model and a type-hint-driven style throughout, which is a bigger shift for a team used to Flask's simpler, synchronous, un-opinionated style, and FastAPI has a smaller, younger ecosystem of plugins/extensions compared to Flask or Django's much longer history.
A client sends a sudden spike of requests that exceeds the configured rate, but the API doesn't immediately reject any of them. Why not, and when does rejection actually start?
The token bucket has accumulated capacity up to the burst limit, if the client had been under the rate limit recently, unused tokens built up in the bucket, and that reserve absorbs a short spike without any request failing, exactly the point of separating burst capacity from steady-state rate. Rejection (a 429 response) only starts once the bucket is actually empty, every accumulated token has been consumed and the spike is sustained long enough that the rate of token consumption keeps exceeding the rate of token replenishment. This is why a token bucket, unlike a hard per-second cap, tolerates brief bursts gracefully while still enforcing a real steady-state ceiling.
When would you choose REST over GraphQL for a new API?
When the API is simple, resource-shaped, and consumed by a small number of known clients with similar needs, REST's simplicity, mature tooling, and native HTTP caching usually win. GraphQL earns its added complexity (schema design, resolver N+1 management, more complex caching) when there are many different client shapes to serve, several frontends, mobile plus web, or third-party API consumers, where flexible field selection meaningfully reduces the number of purpose-built endpoints.
Why does string escaping alone not fully prevent SQL injection?
Escaping tries to neutralize special characters (like quotes) so user input cannot break out of its intended string literal, but it is easy to get wrong, different databases and contexts (string literals, numeric contexts, identifiers, LIKE patterns) have different escaping rules, and a single missed case reopens the vulnerability. Parameterized queries avoid the problem entirely: user input is sent to the database separately from the query structure, so it can never be interpreted as SQL syntax regardless of its content.
REST vs GraphQL
The real trade-offs between REST and GraphQL, over/under-fetching, caching, versioning, and when each one is the better default for an API.
What problem does GraphQL solve that REST does not, structurally?
Over-fetching and under-fetching. A REST endpoint returns a fixed shape, so a mobile client that only needs a user's name either gets the whole user object (over-fetching) or the API team has to add a new endpoint or query params for every new shape a client needs (under-fetching, solved by proliferating endpoints). GraphQL lets the client specify exactly which fields it wants in the query itself, so one flexible schema serves many different client needs without new endpoints.
Why is caching harder with GraphQL than REST?
REST responses map naturally to HTTP caching because a GET to a specific URL returns a predictable resource, so CDNs and browsers can cache by URL. GraphQL typically uses a single POST endpoint with a query body, which defeats standard HTTP/URL-based caching, most GraphQL setups instead rely on client-side normalized caches (like Apollo Client or Relay) keyed by object id and field, or persisted queries plus a CDN cache keyed on the query hash.
gRPC vs REST
How gRPC and REST differ in contracts, transport, streaming, and browser support, and when a binary RPC protocol beats plain HTTP and JSON.
REST vs GraphQL
How REST and GraphQL differ in fetching, caching, and versioning, and which fits a given API better.
Idempotency in Distributed Systems
Why Stripe returns the exact same response, error included, for a reused idempotency key instead of retrying the operation, and why reusing that same key with different parameters is treated as an error, not a new request.
Python Web Frameworks Overview
How Flask, Django, and FastAPI trade minimalism, batteries-included structure, and async-first design differently, and how to actually choose based on project shape.
Rate Limiting Algorithms
How the token bucket algorithm AWS API Gateway actually uses separates a steady-state rate from a burst allowance, and why a request only fails once the bucket is genuinely empty, not the instant the average rate is exceeded.
A client sends a payment request, the network times out before a response arrives, and the client retries with the same idempotency key. What actually happens on the server?
If the original request already completed (successfully or even with an error like a 500) before the retry arrives, the server returns the exact same result it returned (or would have returned) the first time, the same status code and response body, without re-executing the underlying operation, so the customer isn't charged twice just because the client never saw the first response. This is the entire point of an idempotency key: it lets a client safely retry an operation whose actual outcome it's genuinely uncertain about (did the first request even reach the server? did it complete before the timeout?) without that retry risking a duplicate side effect.
Why does reusing the same idempotency key with different request parameters return an error instead of just processing the new parameters?
An idempotency key is a promise that a specific, exact operation happened once; if the same key showed up with different parameters, honoring the new parameters would silently violate that promise; either the original operation's recorded result no longer describes what the key represents, or the client made a mistake by rIeusing a key it should have generated fresh for a genuinely different request. Rejecting the mismatched reuse as an error, rather than guessing which parameters were "correct" or silently processing the new ones, surfaces that client-side mistake immediately instead of masking it.
Why are idempotency keys typically associated with state-changing requests like POST, and are they ever relevant to DELETE?
GET is defined to have no side effects at all, retrying it any number of times simply returns the current state and changes nothing, so there is no duplicate-side-effect risk an idempotency key could protect against, GET genuinely doesn't need one. DELETE is idempotent in the narrow sense that deleting an already-deleted resource is a no-op or a consistent "not found," but whether an idempotency key is relevant to it is API- and version-specific, not settled by the HTTP verb alone: a DELETE can still trigger complex, non-idempotent side effects (a refund, a cascading cleanup, a billing adjustment), and some APIs explicitly accept an idempotency key on DELETE for exactly that reason. Idempotency keys exist to make an operation's retry semantics explicit and safe regardless of whether the underlying operation is inherently idempotent, checking the specific endpoint's documented contract matters more than assuming based on the verb.
What is the core philosophical difference between Flask and Django?
Flask is a microframework; it provides routing and request/response handling and deliberately leaves everything else (ORM, admin panel, authentication, forms) to be chosen and added by the developer. Django is batteries-included; it ships with an ORM, an admin interface, an authentication system, and a forms library as an integrated whole, with strong conventions about how a project should be structured. Flask trades built-in structure for flexibility; Django trades flexibility for a consistent, fully-equipped starting point. Neither is strictly better, the right choice depends on whether a project benefits more from Django's conventions or needs the freedom to pick its own pieces.
Why does the choice between WSGI and ASGI matter when picking a Python web framework?
WSGI (Web Server Gateway Interface) is the traditional, synchronous interface between Python web applications and servers, one request is handled by one worker thread/process at a time, blocking for its duration. ASGI (Asynchronous Server Gateway Interface) extends that to support async request handling and other async protocols (WebSockets), letting a single worker handle many concurrent requests while they're waiting on I/O, the same underlying model as asyncio generally. Flask and Django historically are WSGI (Django has gained ASGI support); FastAPI is ASGI-native. The choice matters because it determines whether the framework can actually benefit from async I/O concurrency, or whether it's fundamentally a one-request-per-worker model regardless of async syntax used inside a handler.
In the token bucket algorithm, what do the "rate" and "burst" settings each actually control?
The rate is how many tokens get added to the bucket per second, the steady-state throughput the API is designed to sustain indefinitely. The burst is the bucket's total capacity, the maximum number of tokens that can accumulate and therefore the largest spike of concurrent requests the API will accept in a single instant before it starts rejecting anything further. A request consumes one token; as long as the bucket has a token available, the request proceeds immediately, rate and burst are two independent numbers, not one combined setting, because sustained throughput and tolerance for short spikes are genuinely different things to configure.
Why would a system use a sliding window rate limiter instead of a token bucket, and what problem does it fix?
A naive fixed window (say, "100 requests per minute, resetting on the minute") allows a client to send 100 requests in the last second of one window and another 100 in the first second of the next, 200 requests in a two-second span despite the stated 100/minute limit, an artifact of the window boundary rather than actual demand. A sliding window rate limiter instead evaluates the limit over a continuously moving time range rather than fixed, discrete buckets, which avoids that boundary-doubling effect at the cost of typically more state to track (timestamps of recent requests, not just a single counter) compared to a token bucket's simpler accumulator model.
Service Mesh Basics
What a sidecar proxy actually intercepts, why service meshes exist once you already have Kubernetes Services, and the mTLS/observability/traffic-shaping capabilities that justify the added complexity.
SQL Injection Prevention
How SQL injection actually works, why parameterized queries are the real fix (not string escaping), and the defense-in-depth practices that back them up.
What is the difference between CloudWatch and CloudTrail?
CloudWatch is the operational observability platform: metrics, logs, dashboards, and alarms that answer "what is the system doing right now," CPU usage, request latency, error rates, application log output. CloudTrail is the audit trail of AWS account activity: a record of API calls and console actions that answers "who did what, when, from where," regardless of whether that action succeeded, failed, or even touched application behavior at all. They are frequently confused because both involve "logs," but CloudWatch Logs holds whatever an application or service chooses to emit, while CloudTrail holds a record of AWS API calls themselves, and neither substitutes for the other.
When would you choose AWS Lambda over EC2 for a workload?
Lambda fits event-driven, short-lived work, an API request, a file landing in S3, a queue message, where you want to pay only for actual invocation time and never manage a server at all; a function can run for at most 15 minutes and has no state between invocations. EC2 fits workloads that need to run continuously, need OS-level control, exceed Lambda's execution-time or memory ceiling, or need to retain in-process state between requests. The decision is about execution model and constraints, not maturity, a long-running stateful service is a worse fit for Lambda regardless of how "serverless-first" a team wants to be.
What is the difference between ECS and EKS?
Both are managed container orchestrators, but ECS is AWS's own native orchestration model (task definitions, services, clusters) with no separate control-plane fee, while EKS runs an actual, standard, upstream Kubernetes control plane that AWS manages for you, and Amazon EKS charges a per-cluster fee specifically for that managed control plane, on top of whatever compute the worker nodes cost. Both can run workloads on EC2 instances you manage, or offload node/workload compute to AWS via Fargate or, on EKS specifically, EKS Auto Mode, so "serverless containers" is available either way; the real choice is whether you want Kubernetes's API and ecosystem (EKS) or a simpler, AWS-native model with less portability (ECS).
What is the difference between S3, EBS, and EFS?
S3 is object storage accessed entirely through an HTTP(S) API, not mounted as a filesystem, built for unstructured data at virtually unlimited scale. EBS is block storage that attaches to exactly one EC2 instance at a time (Multi-Attach for io1/io2 is the narrow exception) and must live in the same Availability Zone as that instance, functioning as its persistent virtual hard disk. EFS is a fully managed NFS file system that is regional by default, replicated across multiple Availability Zones, and can be mounted concurrently by many instances at once. The choice comes down to access pattern: S3 for API-driven object access, EBS for a single instance's own low-latency block storage, EFS for a shared network file system across many instances.
What is an app registration in Entra ID, and why do workloads need one?
An app registration represents an application's identity in Entra ID, giving it a client ID and the ability to authenticate, either as itself (via a client secret or certificate, for service-to-service calls) or on behalf of a signed-in user (via OAuth 2.0/OpenID Connect flows). Workloads need one because Entra ID authentication and authorization apply uniformly to both humans and applications, a background service calling an API needs its own verifiable identity the same way a person does, and an app registration (often combined with a managed identity to avoid handling secrets directly) is how that identity is established.
When would you choose Azure App Service over a Virtual Machine for hosting a web application?
App Service is a fully managed PaaS; it handles OS patching, runtime installation, and built-in scaling and deployment slots, so you only manage application code and configuration. A Virtual Machine is IaaS, full control over the OS and everything installed on it, but you own patching, scaling configuration, and availability yourself. Choose App Service when the workload is a standard web app/API in a supported runtime and the team wants to minimize operational burden; choose a VM when you need OS-level control, unsupported runtimes/dependencies, or specific compliance requirements that mandate managing the host directly.
What does AKS (Azure Kubernetes Service) manage for you compared to running Kubernetes yourself on VMs?
AKS manages the Kubernetes control plane (API server, etcd, scheduler) at no direct cost for the control plane itself; you only pay for the worker nodes, which still run as VMs you have some visibility into but don't have to manually install or upgrade Kubernetes onto. Running Kubernetes yourself on plain VMs means standing up and maintaining the entire control plane, including its high availability and upgrade process, which is a substantial and ongoing operational burden. AKS trades some control-plane visibility for removing that burden, which is why it's the default choice for running Kubernetes on Azure unless there's a specific reason to self-manage.
What is Azure Resource Manager (ARM) and why does every Azure operation go through it?
ARM is the deployment and management layer that every Azure operation, whether from the Portal, CLI, PowerShell, or an ARM/Bicep template, ultimately goes through. It provides a consistent API surface, handles authentication and authorization checks against Azure RBAC, and is what enables declarative deployment (submit a template describing desired resources, ARM figures out what to create/update). Because every path converges on ARM, access control and activity logging are consistent regardless of which tool was used to make a change.
What is the difference between Blob Storage, File Storage, and Disk Storage in Azure?
Blob Storage is object storage for unstructured data (images, backups, logs), accessed via HTTP/HTTPS APIs, not mounted as a filesystem. File Storage provides fully managed file shares accessible via the SMB or NFS protocol, usable as a network drive that multiple VMs can mount simultaneously. Disk Storage provides block-level storage attached to a single VM, functioning as its virtual hard disk. The choice depends on access pattern: Blob for API-driven unstructured data at scale, File for shared network-drive-style access across machines, Disk for a VM's own persistent local-feeling storage.