module CursorPagination
extend ActiveSupport::Concern
private
def paginate_with_cursor(scope, per_page: 20)
class Article < ApplicationRecord
scope :ranked, -> { order(score: :desc, id: :desc) }
scope :after_cursor, ->(cursor) do
return all if cursor.nil?
module KeysetPageable
extend ActiveSupport::Concern
included do
scope :keyset_page, ->(cursor: nil, per: 20) do
per = per.to_i.clamp(1, 100)
class Contract
INVALID = Object.new.freeze
COERCERS = {
string: ->(v) { v.is_a?(String) ? v : v.to_s },
integer: ->(v) { Integer(v.to_s) rescue INVALID },
class CreateApiKeys < ActiveRecord::Migration[6.1]
def change
create_table :api_keys do |t|
t.references :user, null: false, foreign_key: true
t.string :name, null: false
t.string :key_digest, null: false
class RateLimiter
def initialize(key:, limit:, window:)
@key = "rate_limit:#{key}"
@limit = limit
@window = window
end
import { Injectable } from '@nestjs/common';
export interface RateLimitResult {
allowed: boolean;
remaining: number;
limit: number;
export class AppError extends Error {
public readonly statusCode: number;
public readonly code: string;
public readonly isOperational: boolean;
constructor(message: string, statusCode = 500, code = 'INTERNAL_ERROR', isOperational = true) {
package api
import (
"encoding/json"
"net/http"
)
import re
class APIVersionMiddleware:
"""Extract API version from request and add to request object."""
import time
import threading
from collections import deque, defaultdict
class SlidingWindowLimiter:
-- KEYS[1] = current window key, KEYS[2] = previous window key
-- ARGV: limit, window_ms, elapsed_ms
local limit = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local elapsed = tonumber(ARGV[3])