Skip to content

Instantly share code, notes, and snippets.

View nickpoorman's full-sized avatar
Verified

Nick Poorman nickpoorman

Verified
View GitHub Profile
@nickpoorman
nickpoorman / gitignore
Created March 14, 2013 00:36
gitignore problem
# node.js #
###########
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
@nickpoorman
nickpoorman / .gitignore
Created October 11, 2013 07:16
.gitignore
# node.js #
###########
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
@nickpoorman
nickpoorman / repl.js
Created July 9, 2014 21:15
Simple repl for rethinkdb
/**
* simple repl for the database
*/
var r = require('rethinkdb');
var inspect = require('util').inspect;
var connectOpts = {
host: process.HOST || '127.0.0.1',
port: process.PORT || 28015,
};

Keybase proof

I hereby claim:

  • I am nickpoorman on github.
  • I am nickpoorman (https://keybase.io/nickpoorman) on keybase.
  • I have a public key whose fingerprint is F54D 717B 258B F44B A8F3 893B 59CC 07EF B0FC 5E29

To claim this, I am signing this object:

# app/controllers/application_controller.rb
class ApplicationController < ActionController::API
include Pundit
# set current_user from token
include DeviseTokenAuth::Concerns::SetUserByToken
# For this example we will stub out `current_user`
# For Pundit, you may want to override `pundit_user`
def current_user
# app/graph/application_schema.rb
ApplicationSchema = GraphQL::Schema.define do
query QueryType
mutation MutationType
resolve_type -> (object, _ctx) { ApplicationSchema.types[object.class.name] }
# These are used by relay
object_from_id -> (id, ctx) { decode_object(id, ctx) }
id_from_object -> (obj, type, ctx) { encode_object(obj, type, ctx) }
# app/controllers/graphql_controller.rb
class GraphqlController < ApplicationController
def create
query_string = params[:query]
query_variables = ensure_hash(params[:variables])
context = { current_user: current_user, pundit: self }
result = ApplicationSchema.execute(query_string, variables: query_variables, context: context)
render json: result
end
# app/graph/fields/fetch_field.rb
class FetchField < GraphQL::Field
def initialize(model:, type:)
self.type = type
@model = model
self.description = 'Find a #{model.name} by ID'
self.arguments = {
'id' => GraphQL::Argument.define do
name 'id'
type !GraphQL::INT_TYPE
# app/graph/mutations/post_mutations/create.rb
module PostMutations
Create = GraphQL::Relay::Mutation.define do
# Used to name derived types, eg `"CreatePostInput"`:
name 'CreatePost'
description 'Create post with a title and return a post'
# Define input parameters
# Accessible from `input` in the resolve function:
input_field :title, !types.String

Scaling your API with rate limiters

The following are examples of the four types rate limiters discussed in the accompanying blog post. In the examples below I've used pseudocode-like Ruby, so if you're unfamiliar with Ruby you should be able to easily translate this approach to other languages. Complete examples in Ruby are also provided later in this gist.

In most cases you'll want all these examples to be classes, but I've used simple functions here to keep the code samples brief.

Request rate limiter

This uses a basic token bucket algorithm and relies on the fact that Redis scripts execute atomically. No other operations can run between fetching the count and writing the new count.