Example plan

rate-limit.yaml

New here? Get started. See Running the examplesfor this plan's fixture, runtime, database or browser requirements. The exec example needs no fixture; Postgres and Playwright need their optional dependencies.

Four requests spend a budget of three; the fourth must be refused. Three tasks use the same API key's budget, so all three hold one resource, and the key is reset before the run. Start bin/vero-testserver in Terminal 1; run bin/vero run examples/rate-limit.yaml in Terminal 2.

apiVersion: vero.plan/v1
kind: Plan
metadata:
  name: example-rate-limit
env:
  baseUrl: http://127.0.0.1:18080
  apiKey: m0-key

lifecycle:
  strategy: reset
  reset:
    - http: { method: POST, url: "{{ env.baseUrl }}/admin/ratelimit/reset", json: { key: "{{ env.apiKey }}" } }
      timeout: 10s
      assert: [status == 204]

resources:
  - name: ratelimit/orders-api-key
    mode: exclusive

tasks:
  - name: login
    steps:
      - http: { method: POST, url: "{{ env.baseUrl }}/auth/token", json: { key: "{{ env.apiKey }}" } }
        assert: [status == 200, body.token != nil]
        results: { token: body.token }

  - name: rate-limit-trips-on-fourth
    holds: [ratelimit/orders-api-key]
    steps:
      - http:
          method: GET
          url: "{{ env.baseUrl }}/orders"
          headers: { Authorization: "Bearer {{ tasks.login.results.token }}" }
        repeat: { count: 4, mode: serial }
        assert:
          - responses count 4
          - responses[0:3] all (it.status == 200)
          - responses[3].status == 429
          - responses[3].headers["Retry-After"] != nil

  - name: pagination            # spends the same budget, so it holds the same resource
    holds: [ratelimit/orders-api-key]
    steps:
      - http: { method: POST, url: "{{ env.baseUrl }}/admin/ratelimit/reset", headers: { Authorization: "Bearer {{ tasks.login.results.token }}" } }
        assert: [status == 204]
      - http: { method: GET, url: "{{ env.baseUrl }}/orders", query: { page: "1", limit: "2" }, headers: { Authorization: "Bearer {{ tasks.login.results.token }}" } }
        assert: [status == 200]
      - http: { method: POST, url: "{{ env.baseUrl }}/admin/ratelimit/reset", headers: { Authorization: "Bearer {{ tasks.login.results.token }}" } }
        assert: [status == 204]

  - name: filtering
    holds: [ratelimit/orders-api-key]
    steps:
      - http: { method: POST, url: "{{ env.baseUrl }}/admin/ratelimit/reset", headers: { Authorization: "Bearer {{ tasks.login.results.token }}" } }
        assert: [status == 204]
      - http: { method: GET, url: "{{ env.baseUrl }}/orders", query: { status: pending }, headers: { Authorization: "Bearer {{ tasks.login.results.token }}" } }
        assert: [status == 200]
      - http: { method: POST, url: "{{ env.baseUrl }}/admin/ratelimit/reset", headers: { Authorization: "Bearer {{ tasks.login.results.token }}" } }
        assert: [status == 204]

This page is examples/rate-limit.yaml in the repository.

verodocs