Callum Slater

Callum Slater

1550715964

Pagination with JsonResponse

I'd like to add pagination to my JsonResponse.

I'm currently using the django.http.JsonResponse to generate json from an elastic search API. I'd like to add a pagination feature to be included. My code is as follows:

class ResultQueryView(View):
    def get(self, request):
        resource_meta = request.GET.getlist("resource_meta")
        locations = request.GET.getlist("location")
        page = request.GET.get("page")
        logger.info("Got search query where resource_meta: {} and locations: {}".format(resource_meta, locations))
        results = resource_query(resource_meta, locations)
        resource_ids = [r["_id"] for r in results['hits']['hits']]
        resources = get_enriched_resources(request.user, Resource.objects.filter(internal_id__in=resource_ids))
        serialized = ResourceSerializer(resources, many=True)
        return JsonResponse({"resources": serialized.data})


#django

What is GEEK

Buddha Community

Use Django’s Paginator.

from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
class ViewPaginatorMixin(object):
    min_limit = 1
    max_limit = 10

    def paginate(self, object_list, page=1, limit=10, **kwargs):
        try:
            page = int(page)
            if page < 1:
                page = 1
        except (TypeError, ValueError):
            page = 1

        try:
            limit = int(limit)
            if limit < self.min_limit:
                limit = self.min_limit
            if limit > self.max_limit:
                limit = self.max_limit
        except (ValueError, TypeError):
            limit = self.max_limit

        paginator = Paginator(object_list, limit)
        try:
            objects = paginator.page(page)
        except PageNotAnInteger:
            objects = paginator.page(1)
        except EmptyPage:
            objects = paginator.page(paginator.num_pages)
        data = {
            'previous_page': objects.has_previous() and objects.previous_page_number() or None,
            'next_page': objects.has_next() and objects.next_page_number() or None,
            'data': list(objects)
        }
        return data

Now, use the ViewPaginatorMixin to support pagination for View

class ResultQueryView(ViewPaginatorMixin, View):
    def get(self, request):
       // code
       serialized = ResourceSerializer(resources, many=True)
       return JsonResponse({"resources": self.paginate(serialized.data, page, limit)})

Pagination Example In Laravel

In this post I will show you pagination example in laravel, as we all know pagination is very common feature in all websites, if we want to display specific number of details or images then we can use pagination.

aravel provide paginate method and it will automatically takes care of setting the proper limit and offset based on the current page being viewed by the user.here i will show you how to use pagination in laravel, So I have try paginate method in laravel.

Pagination Example In Laravel

https://websolutionstuff.com/post/pagination-example-in-laravel

#pagination example in laravel #laravel #pagination #paginate method #how to use pagination in laravel #pagination in laravel

Josefa  Corwin

Josefa Corwin

1659736920

Mailboxer: A Rails Gem to Send Messages inside A Web Application

Mailboxer

This project is based on the need for a private message system for ging / social_stream. Instead of creating our core message system heavily dependent on our development, we are trying to implement a generic and potent messaging gem.

After looking for a good gem to use we noticed the lack of messaging gems and functionality in them. Mailboxer tries to fill this void delivering a powerful and flexible message system. It supports the use of conversations with two or more participants, sending notifications to recipients (intended to be used as system notifications “Your picture has new comments”, “John Doe has updated his document”, etc.), and emailing the messageable model (if configured to do so). It has a complete implementation of a Mailbox object for each messageable with inbox, sentbox and trash.

The gem is constantly growing and improving its functionality. As it is used with our parallel development ging / social_stream we are finding and fixing bugs continously. If you want some functionality not supported yet or marked as TODO, you can create an issue to ask for it. It will be great feedback for us, and we will know what you may find useful in the gem.

Mailboxer was born from the great, but outdated, code from lpsergi / acts_as_messageable.

We are now working to make exhaustive documentation and some wiki pages in order to make it even easier to use the gem to its full potential. Please, give us some time if you find something missing or ask for it. You can also find us on the Gitter room for this repo. Join us there to talk.

Installation

Add to your Gemfile:

gem 'mailboxer'

Then run:

$ bundle install

Run install script:

$ rails g mailboxer:install

And don't forget to migrate your database:

$ rake db:migrate

You can also generate email views:

$ rails g mailboxer:views

Upgrading

If upgrading from 0.11.0 to 0.12.0, run the following generators:

$ rails generate mailboxer:namespacing_compatibility
$ rails generate mailboxer:install -s

Then, migrate your database:

$ rake db:migrate

Requirements & Settings

Emails

We are now adding support for sending emails when a Notification or a Message is sent to one or more recipients. You should modify the mailboxer initializer (/config/initializer/mailboxer.rb) to edit these settings:

Mailboxer.setup do |config|
  #Enables or disables email sending for Notifications and Messages
  config.uses_emails = true
  #Configures the default `from` address for the email sent for Messages and Notifications of Mailboxer
  config.default_from = "no-reply@dit.upm.es"
  ...
end

You can change the way in which emails are delivered by specifying a custom implementation of notification and message mailers:

Mailboxer.setup do |config|
  config.notification_mailer = CustomNotificationMailer
  config.message_mailer = CustomMessageMailer
  ...
end

If you have subclassed the Mailboxer::Notification class, you can specify the mailers using a member method:

class NewDocumentNotification < Mailboxer::Notification
  def mailer_class
    NewDocumentNotificationMailer
  end
end

class NewCommentNotification < Mailboxer::Notification
  def mailer_class
    NewDocumentNotificationMailer
  end
end

Otherwise, the mailer class will be determined by appending 'Mailer' to the mailable class name.

User identities

Users must have an identity defined by a name and an email. We must ensure that Messageable models have some specific methods. These methods are:

#Returning any kind of identification you want for the model
def name
  return "You should add method :name in your Messageable model"
end
#Returning the email address of the model if an email should be sent for this object (Message or Notification).
#If no mail has to be sent, return nil.
def mailboxer_email(object)
  #Check if an email should be sent for that object
  #if true
  return "define_email@on_your.model"
  #if false
  #return nil
end

These names are explicit enough to avoid colliding with other methods, but as long as you need to change them you can do it by using mailboxer initializer (/config/initializer/mailboxer.rb). Just add or uncomment the following lines:

Mailboxer.setup do |config|
  # ...
  #Configures the methods needed by mailboxer
  config.email_method = :mailboxer_email
  config.name_method = :name
  config.notify_method = :notify
  # ...
end

You may change whatever you want or need. For example:

config.email_method = :notification_email
config.name_method = :display_name
config.notify_method = :notify_mailboxer

Will use the method notification_email(object) instead of mailboxer_email(object), display_name for name and notify_mailboxer for notify.

Using default or custom method names, if your model doesn't implement them, Mailboxer will use dummy methods so as to notify you of missing methods rather than crashing.

Preparing your models

In your model:

class User < ActiveRecord::Base
  acts_as_messageable
end

You are not limited to the User model. You can use Mailboxer in any other model and use it in several different models. If you have ducks and cylons in your application and you want to exchange messages as if they were the same, just add acts_as_messageable to each one and you will be able to send duck-duck, duck-cylon, cylon-duck and cylon-cylon messages. Of course, you can extend it for as many classes as you need.

Example:

class Duck < ActiveRecord::Base
  acts_as_messageable
end
class Cylon < ActiveRecord::Base
  acts_as_messageable
end

Mailboxer API

Warning for version 0.8.0

Version 0.8.0 sees Messageable#read and Messageable#unread renamed to mark_as_(un)read, and Receipt#read and Receipt#unread to is_(un)read. This may break existing applications, but read is a reserved name for Active Record, and the best pratice in this case is simply avoid using it.

How can I send a message?

#alfa wants to send a message to beta
alfa.send_message(beta, "Body", "subject")

How can I read the messages of a conversation?

As a messageable, what you receive are receipts, which are associated with the message itself. You should retrieve your receipts for the conversation and get the message associated with them.

This is done this way because receipts save the information about the relation between messageable and the messages: is it read?, is it trashed?, etc.

#alfa gets the last conversation (chronologically, the first in the inbox)
conversation = alfa.mailbox.inbox.first

#alfa gets it receipts chronologically ordered.
receipts = conversation.receipts_for alfa

#using the receipts (i.e. in the view)
receipts.each do |receipt|
  ...
  message = receipt.message
  read = receipt.is_unread? #or message.is_unread?(alfa)
  ...
end

How can I reply to a message?

#alfa wants to reply to all in a conversation
#using a receipt
alfa.reply_to_all(receipt, "Reply body")

#using a conversation
alfa.reply_to_conversation(conversation, "Reply body")
#alfa wants to reply to the sender of a message (and ONLY the sender)
#using a receipt
alfa.reply_to_sender(receipt, "Reply body")

How can I delete a message from trash?

#delete conversations forever for one receipt (still in database)
receipt.mark_as_deleted

#you can mark conversation as deleted for one participant
conversation.mark_as_deleted participant

#Mark the object as deleted for messageable
#Object can be:
  #* A Receipt
  #* A Conversation
  #* A Notification
  #* A Message
  #* An array with any of them
alfa.mark_as_deleted conversation

# get available message for specific user
conversation.messages_for(alfa)

How can I retrieve my conversations?

#alfa wants to retrieve all his conversations
alfa.mailbox.conversations

#A wants to retrieve his inbox
alfa.mailbox.inbox

#A wants to retrieve his sent conversations
alfa.mailbox.sentbox

#alfa wants to retrieve his trashed conversations
alfa.mailbox.trash

How can I paginate conversations?

You can use Kaminari to paginate the conversations as normal. Please, make sure you use the last version as mailboxer uses select('DISTINCT conversations.*') which was not respected before Kaminari 0.12.4 according to its changelog. Working correctly on Kaminari 0.13.0.

#Paginating all conversations using :page parameter and 9 per page
conversations = alfa.mailbox.conversations.page(params[:page]).per(9)

#Paginating received conversations using :page parameter and 9 per page
conversations = alfa.mailbox.inbox.page(params[:page]).per(9)

#Paginating sent conversations using :page parameter and 9 per page
conversations = alfa.mailbox.sentbox.page(params[:page]).per(9)

#Paginating trashed conversations using :page parameter and 9 per page
conversations = alfa.mailbox.trash.page(params[:page]).per(9)

You can take a look at the full documentation for Mailboxer in rubydoc.info.

Do you want to test Mailboxer?

Thanks to Roman Kushnir (@RKushnir) you can test Mailboxer with this sample app.

I need a GUI!

If you need a GUI you should take a look at these links:

Contributors


Author: mailboxer
Source code: https://github.com/mailboxer/mailboxer
License: MIT license

#ruby  #ruby-on-rails 

Royce  Reinger

Royce Reinger

1613705775

Angular 11 Pagination Example with ngx-pagination

In this tutorial, I will show you how to make Angular 11 Pagination example with existing API (server-side pagination) using ngx-pagination.

Overview of Angular 11 Pagination example

One of the most important things to make a website friendly is the response time, and pagination comes for this reason. For example, this bezkoder.com website has hundreds of tutorials, and we don’t want to see all of them at once. Paging means displaying a small number of all, by a page.

Assume that we have tutorials table in database like this:

angular-11-pagination-example-ngx-pagination-database

Our Angular 11 app will display the result with pagination:

angular-11-pagination-example-ngx-pagination-default-paging

You can change to a page with larger index:

#angular #angular #angular 11 #ngx-pagination #pagination

I am Developer

1597475374

Laravel - Livewwire Search with Pagination

In this post, i will show you how to create livewire search with pagination in laravel app. You just follow the below steps and create laravel livewire search with pagination app.

Laravel Livewire Search with Pagination

Follow below simple & easy steps to implement livewire search with pagination in laravel app:

Step 1: Install Laravel App
Step 2: Add Database Detail
Step 3: Create Model & Migration using Artisan
Step 4: Install Livewire Package
Step 5: Create Component using Artisan
Step 6: Add Route
Step 7: Create View File
Step 8: Run Development Server

https://www.tutsmake.com/laravel-livewire-pagination-with-search-step-by-step/

#laravel livewwire search with pagination #livewwire search with pagination #search with pagination in laravel livewire

Build JSON API-compliant APIs on Rails with No Learning Curve

JSONAPI::Utils  

Simple yet powerful way to get your Rails API compliant with JSON API.

JSONAPI::Utils (JU) is built on top of JSONAPI::Resources taking advantage of its resource-driven style and bringing a set of helpers to easily build modern JSON APIs with no or less learning curve.

After installing the gem and defining the resources/routes, it's as simple as calling a render helper:

class UsersController < ActionController::Base
  include JSONAPI::Utils

  def index
    jsonapi_render json: User.all
  end
end

Installation

Support:

  • Ruby 1.9+ with Rails 4
  • Ruby 2.4+ with Rails 5

For Rails 4 add this to your application's Gemfile:

gem 'jsonapi-utils', '~> 0.4.9'

For Rails 5+:

gem 'jsonapi-utils', '~> 0.7.3'

And then execute:

$ bundle

Why JSONAPI::Utils?

One of the main motivations behind JSONAPI::Utils is to keep things explicit in controllers (no hidden actions :-) so that developers can easily understand and maintain their code.

Unlike JSONAPI::Resources (JR), JU doesn't care about how you will operate your controller actions. The gem deals only with the request validation and response rendering (via JR's objects) and provides a set of helpers (renders, formatters etc) along the way. Thus developers can decide how to actually operate their actions: service objects, interactors etc.

Usage

Response

Renders

JU brings two main renders to the game, working pretty much the same way as Rails' ActionController#render method:

  • jsonapi_render
  • jsonapi_render_errors

jsonapi_render

It renders a JSON API-compliant response.

# app/controllers/users_controller.rb
# GET /users
def index
  jsonapi_render json: User.all
end

# GET /users/:id
def show
  jsonapi_render json: User.find(params[:id])
end

Arguments:

  • json: object to be rendered as a JSON document: ActiveRecord object, Hash or Array;
  • status: HTTP status code (Integer, String or Symbol). If ommited a status code will be automatically infered;
  • options:
    • resource: explicitly points the resource to be used in the serialization. By default, JU will select resources by inferencing from controller's name.
    • count: explicitly points the total count of records for the request in order to build a proper pagination. By default, JU will count the total number of records.
    • model: sets the model reference in cases when json is a Hash or a collection of Hashes.

Other examples:

# Specify a particular HTTP status code
jsonapi_render json: new_user, status: :created

# Forcing a different resource
jsonapi_render json: User.all, options: { resource: V2::UserResource }

# Using a specific count
jsonapi_render json: User.some_weird_scope, options: { count: User.some_weird_scope_count }

# Hash rendering
jsonapi_render json: { data: { id: 1, first_name: 'Tiago' } }, options: { model: User }

# Collection of Hashes rendering
jsonapi_render json: { data: [{ id: 1, first_name: 'Tiago' }, { id: 2, first_name: 'Doug' }] }, options: { model: User }

jsonapi_render_errors

It renders a JSON API-compliant error response.

# app/controllers/users_controller.rb
# POST /users
  def create
    user = User.new(user_params)
    if user.save
      jsonapi_render json: user, status: :created
    else
      jsonapi_render_errors json: user, status: :unprocessable_entity
    end
  end

Arguments:

  • Exception
  • json: object to be rendered as a JSON document: ActiveRecord, Exception, Array or any object which implements the errors method;
  • status: HTTP status code (Integer, String or Symbol). If ommited a status code will be automatically infered from the error body.

Other examples:

# Render errors from a custom exception:
jsonapi_render_errors Exceptions::MyCustomError.new(user)

# Render errors from an Array<Hash>:
errors = [{ id: 'validation', title: 'Something went wrong', code: '100' }]
jsonapi_render_errors json: errors, status: :unprocessable_entity

Formatters

In the backstage these are the guys which actually parse the ActiveRecord/Hash object to build a new Hash compliant with JSON API's specs. Formatters can be called anywhere in controllers being very useful if you need to do some work with the response's body before rendering the actual response.

Note: the resulting Hash from those methods can not be passed as argument to JSONAPI::Utils#jsonapi_render or JSONAPI::Utils#jsonapi_render_error, instead it needs to be rendered by the usual ActionController#render.

jsonapi_format

Because of semantic reasons JSONAPI::Utils#jsonapi_serialize was renamed to JSONAPI::Utils#jsonapi_format.

# app/controllers/users_controller.rb
def index
  body = jsonapi_format(User.all)
  render json: do_some_magic_with(body)
end

Arguments:

  • First: ActiveRecord object, Hash or Array;
  • Last: Hash of options (same as JSONAPI::Utils#jsonapi_render).

Paginators

Pagination works out of the box on JU, you just need to decide which kind of paginator you'd like to use.

It's really easy to work with pagination on JU, actually it's just a matter of chosing the paginator you wish in your JR's config file:

# config/initializers/jsonapi_resources.rb
JSONAPI.configure do |config|
  # :none, :offset, :paged, or a custom paginator name
  config.default_paginator = :paged

  # Output pagination links at top level
  config.top_level_links_include_pagination = true
  
  # Default sizes
  config.default_page_size = 70
  config.maximum_page_size = 100
end

As you may have noticed above, it's possible to use custom paginators. In order to create your own paginator your just need to define a class which inherits from JSONAPI::Paginator and implements the #pagination_range method which in turn must return the range to be applied over the resulting collection.

For example, if you would like to paginate over a collection of hashes, you may implement the #pagination_range method as below:

class CustomPaginator < JSONAPI::Paginator
  def pagination_range(page_params)
    offset = page_params['offset']
    limit  = JSONAPI.configuration.default_page_size
    offset..offset + limit - 1 # resulting range
  end

And then it can be either set at the resource class level (e.g. UserResource.paginator :custom) or via config initializer:

# config/initializers/jsonapi_resources.rb
JSONAPI.configure do |config|
  config.default_paginator = :custom
end

Request

Before a controller action gets executed, JSONAPI::Utils will validate the request against JSON API's specs as well as evaluating the eventual query string params to check if they match the resource's definition. If something goes wrong during the validation process, JU will render an error response like this examples below:

HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json

{
  "errors": [
    {
      "title": "Invalid resource",
      "detail": "foo is not a valid resource.",
      "code": "101",
      "status": "400"
    },
    {
      "title": "Invalid resource",
      "detail": "foobar is not a valid resource.",
      "code": "101",
      "status": "400"
    },
    {
      "title": "Invalid field",
      "detail": "bar is not a valid relationship of users",
      "code": "112",
      "status": "400"
    }
  ]
}

Params helpers

JU brings helper methods as a shortcut to get values from permitted params based on the resource's configuration.

  • resource_params:
    • Returns the permitted params present in the attributes JSON member;
      • Example: { name: 'Bilbo', gender: 'male', city: 'Shire' }
    • Same of calling: params.require(:data).require(:attributes).permit(:name, :gender, :city)
  • relationship_params:
    • Returns the relationship ids, distinguished by key, present in relationships JSON member;
      • Example: { author: 1, posts: [1, 2, 3] }
    • Same as calling: params.require(:relationships).require(:author).require(:data).permit(:id)

Full example

After installing the gem you simply need to:

  1. Include the gem's module (include JSONAPI::Utils) in a controller (eg. BaseController);
  2. Define the resources which will be exposed via REST API;
  3. Define the application's routes;
  4. Use JSONAPI Utils' helper methods (eg. renders, formatters, params helpers etc).

Ok, now it's time to start our complete example. So, let's say we have a Rails application for a super simple blog:

Models

# app/models/user.rb
class User < ActiveRecord::Base
  has_many :posts
  validates :first_name, :last_name, presence: true
end

# app/models/post.rb
class Post < ActiveRecord::Base
  belongs_to :author, class_name: 'User', foreign_key: 'user_id'
  validates :title, :body, presence: true
end

Resources

Here is where we define how our models are exposed as resources on the API:

# app/resources/user_resource.rb
class UserResource < JSONAPI::Resource
  attributes :first_name, :last_name, :full_name, :birthday

  has_many :posts

  def full_name
    "#{@model.first_name} #{@model.last_name}"
  end
end

# app/resources/post_resource.rb
class PostResource < JSONAPI::Resource
  attributes :title, :body
  has_one :author
end

Routes & Controllers

Let's define the routes using the jsonapi_resources method provided by JR:

Rails.application.routes.draw do
  jsonapi_resources :users do
    jsonapi_resources :posts
  end
end

In controllers we just need to include the JSONAPI::Utils module.

Note: some default rendering can be set like the below example where jsonapi_render_not_found is used when a record is not found in the database.

# app/controllers/base_controller.rb
class BaseController < ActionController::Base
  include JSONAPI::Utils
  protect_from_forgery with: :null_session
  rescue_from ActiveRecord::RecordNotFound, with: :jsonapi_render_not_found
end

With the helper methods inhirited from JSONAPI::Utils in our BaseController, now it's all about to write our actions like the following:

# app/controllers/users_controller.rb
class UsersController < BaseController
  # GET /users
  def index
    users = User.all
    jsonapi_render json: users
  end

  # GET /users/:id
  def show
    user = User.find(params[:id])
    jsonapi_render json: user
  end

  # POST /users
  def create
    user = User.new(resource_params)
    if user.save
      jsonapi_render json: user, status: :created
    else
      jsonapi_render_errors json: user, status: :unprocessable_entity
    end
  end

  # PATCH /users/:id
  def update
    user = User.find(params[:id])
    if user.update(resource_params)
      jsonapi_render json: user
    else
      jsonapi_render_errors json: user, status: :unprocessable_entity
    end
  end

  # DELETE /users/:id
  def destroy
    User.find(params[:id]).destroy
    head :no_content
  end
end

And:

# app/controllers/posts_controller.rb
class PostsController < BaseController
  before_action :load_user, except: :create

  # GET /users/:user_id/posts
  def index
    jsonapi_render json: @user.posts, options: { count: 100 }
  end

  # GET /users/:user_id/posts/:id
  def show
    jsonapi_render json: @user.posts.find(params[:id])
  end

  # POST /posts
  def create
    post = Post.new(post_params)
    if post.save
      jsonapi_render json: post, status: :created
    else
      jsonapi_render_errors json: post, status: :unprocessable_entity
    end
  end

  private

  def post_params
    resource_params.merge(user_id: relationship_params[:author])
  end

  def load_user
    @user = User.find(params[:user_id])
  end
end

Initializer

In order to enable a proper pagination, record count etc, an initializer could be defined such as:

# config/initializers/jsonapi_resources.rb
JSONAPI.configure do |config|
  config.json_key_format = :underscored_key
  config.route_format = :dasherized_route

  config.allow_include = true
  config.allow_sort = true
  config.allow_filter = true

  config.raise_if_parameters_not_allowed = true

  config.default_paginator = :paged

  config.top_level_links_include_pagination = true

  config.default_page_size = 10
  config.maximum_page_size = 20

  config.top_level_meta_include_record_count = true
  config.top_level_meta_record_count_key = :record_count

  config.top_level_meta_include_page_count = true
  config.top_level_meta_page_count_key = :page_count

  config.use_text_errors = false

  config.exception_class_whitelist = []

  config.always_include_to_one_linkage_data = false
end

You may want a different configuration for your API. For more information check this.

Requests & Responses

Here are examples of requests – based on those sample controllers – and their respective JSON responses.

Index

Request:

GET /users HTTP/1.1
Accept: application/vnd.api+json

Response:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "data": [
    {
      "id": "1",
      "type": "users",
      "links": {
        "self": "http://api.myblog.com/users/1"
      },
      "attributes": {
        "first_name": "Tiago",
        "last_name": "Guedes",
        "full_name": "Tiago Guedes",
        "birthday": null
      },
      "relationships": {
        "posts": {
          "links": {
            "self": "http://api.myblog.com/users/1/relationships/posts",
            "related": "http://api.myblog.com/users/1/posts"
          }
        }
      }
    },
    {
      "id": "2",
      "type": "users",
      "links": {
        "self": "http://api.myblog.com/users/2"
      },
      "attributes": {
        "first_name": "Douglas",
        "last_name": "André",
        "full_name": "Douglas André",
        "birthday": null
      },
      "relationships": {
        "posts": {
          "links": {
            "self": "http://api.myblog.com/users/2/relationships/posts",
            "related": "http://api.myblog.com/users/2/posts"
          }
        }
      }
    }
  ],
  "meta": {
    "record_count": 2
  },
  "links": {
    "first": "http://api.myblog.com/users?page%5Bnumber%5D=1&page%5Bsize%5D=10",
    "last": "http://api.myblog.com/users?page%5Bnumber%5D=1&page%5Bsize%5D=10"
  }
}

Index (options)

Request:

GET /users?include=posts&fields[users]=first_name,last_name,posts&fields[posts]=title&sort=first_name,last_name&page[number]=1&page[size]=1 HTTP/1.1
Accept: application/vnd.api+json

Response:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "data": [
    {
      "id": "2",
      "type": "users",
      "links": {
        "self": "http://api.myblog.com/users/2"
      },
      "attributes": {
        "first_name": "Douglas",
        "last_name": "André"
      },
      "relationships": {
        "posts": {
          "links": {
            "self": "http://api.myblog.com/users/2/relationships/posts",
            "related": "http://api.myblog.com/users/2/posts"
          },
          "data": []
        }
      }
    },
    {
      "id": "1",
      "type": "users",
      "links": {
        "self": "http://api.myblog.com/users/1"
      },
      "attributes": {
        "first_name": "Tiago",
        "last_name": "Guedes"
      },
      "relationships": {
        "posts": {
          "links": {
            "self": "http://api.myblog.com/users/1/relationships/posts",
            "related": "http://api.myblog.com/users/1/posts"
          },
          "data": [
            {
              "type": "posts",
              "id": "1"
            }
          ]
        }
      }
    }
  ],
  "included": [
    {
      "id": "1",
      "type": "posts",
      "links": {
        "self": "http://api.myblog.com/posts/1"
      },
      "attributes": {
        "title": "An awesome post"
      }
    }
  ],
  "meta": {
    "record_count": 2
  },
  "links": {
    "first": "http://api.myblog.com/users?fields%5Bposts%5D=title&fields%5Busers%5D=first_name%2Clast_name%2Cposts&include=posts&page%5Blimit%5D=2&page%5Boffset%5D=0&sort=first_name%2Clast_name",
    "last": "http://api.myblog.com/users?fields%5Bposts%5D=title&fields%5Busers%5D=first_name%2Clast_name%2Cposts&include=posts&page%5Blimit%5D=2&page%5Boffset%5D=0&sort=first_name%2Clast_name"
  }
}

Show

Request:

GET /users/1 HTTP/1.1
Accept: application/vnd.api+json

Response:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "data": {
    "id": "1",
    "type": "users",
    "links": {
      "self": "http://api.myblog.com/users/1"
    },
    "attributes": {
      "first_name": "Tiago",
      "last_name": "Guedes",
      "full_name": "Tiago Guedes",
      "birthday": null
    },
    "relationships": {
      "posts": {
        "links": {
          "self": "http://api.myblog.com/users/1/relationships/posts",
          "related": "http://api.myblog.com/users/1/posts"
        }
      }
    }
  }
}

Show (options)

Request:

GET /users/1?include=posts&fields[users]=full_name,posts&fields[posts]=title HTTP/1.1
Accept: application/vnd.api+json

Response:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "data": {
    "id": "1",
    "type": "users",
    "links": {
      "self": "http://api.myblog.com/users/1"
    },
    "attributes": {
      "full_name": "Tiago Guedes"
    },
    "relationships": {
      "posts": {
        "links": {
          "self": "http://api.myblog.com/users/1/relationships/posts",
          "related": "http://api.myblog.com/users/1/posts"
        },
        "data": [
          {
            "type": "posts",
            "id": "1"
          }
        ]
      }
    }
  },
  "included": [
    {
      "id": "1",
      "type": "posts",
      "links": {
        "self": "http://api.myblog.com/posts/1"
      },
      "attributes": {
        "title": "An awesome post"
      }
    }
  ]
}

Relationships (identifier objects)

Request:

GET /users/1/relationships/posts HTTP/1.1
Accept: application/vnd.api+json

Response:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "http://api.myblog.com/users/1/relationships/posts",
    "related": "http://api.myblog.com/users/1/posts"
  },
  "data": [
    {
      "type": "posts",
      "id": "1"
    }
  ]
}

Nested resources

Request:

GET /users/1/posts HTTP/1.1
Accept: application/vnd.api+json

Response:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "data": [
    {
      "id": "1",
      "type": "posts",
      "links": {
        "self": "http://api.myblog.com/posts/1"
      },
      "attributes": {
        "title": "An awesome post",
        "body": "Lorem ipsum dolot sit amet"
      },
      "relationships": {
        "author": {
          "links": {
            "self": "http://api.myblog.com/posts/1/relationships/author",
            "related": "http://api.myblog.com/posts/1/author"
          }
        }
      }
    }
  ],
  "meta": {
    "record_count": 1
  },
  "links": {
    "first": "http://api.myblog.com/posts?page%5Bnumber%5D=1&page%5Bsize%5D=10",
    "last": "http://api.myblog.com/posts?page%5Bnumber%5D=1&page%5Bsize%5D=10"
  }
}

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake rspec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/tiagopog/jsonapi-utils. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.


Author: tiagopog
Source code: https://github.com/tiagopog/jsonapi-utils
License: MIT license

#ruby #ruby-on-rails