1550715964
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
1550717875
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)})
1622006340
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 #laravel #pagination #paginate method #how to use pagination in laravel #pagination in laravel
1659736920
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.
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
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
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.
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.
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
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.
#alfa wants to send a message to beta
alfa.send_message(beta, "Body", "subject")
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
#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")
#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)
#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
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.
Thanks to Roman Kushnir (@RKushnir) you can test Mailboxer with this sample app.
If you need a GUI you should take a look at these links:
Author: mailboxer
Source code: https://github.com/mailboxer/mailboxer
License: MIT license
1613705775
In this tutorial, I will show you how to make Angular 11 Pagination example with existing API (server-side pagination) using ngx-pagination.
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:
Our Angular 11 app will display the result with pagination:
You can change to a page with larger index:
#angular #angular #angular 11 #ngx-pagination #pagination
1597475374
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.
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
1659303060
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
Support:
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
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.
JU brings two main renders to the game, working pretty much the same way as Rails' ActionController#render
method:
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:
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
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
orJSONAPI::Utils#jsonapi_render_error
, instead it needs to be rendered by the usualActionController#render
.
jsonapi_format
Because of semantic reasons
JSONAPI::Utils#jsonapi_serialize
was renamed toJSONAPI::Utils#jsonapi_format
.
# app/controllers/users_controller.rb
def index
body = jsonapi_format(User.all)
render json: do_some_magic_with(body)
end
Arguments:
JSONAPI::Utils#jsonapi_render
).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
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"
}
]
}
JU brings helper methods as a shortcut to get values from permitted params based on the resource's configuration.
resource_params
:attributes
JSON member;{ name: 'Bilbo', gender: 'male', city: 'Shire' }
params.require(:data).require(:attributes).permit(:name, :gender, :city)
relationship_params
:id
s, distinguished by key, present in relationships
JSON member;{ author: 1, posts: [1, 2, 3] }
params.require(:relationships).require(:author).require(:data).permit(:id)
After installing the gem you simply need to:
include JSONAPI::Utils
) in a controller (eg. BaseController
);Ok, now it's time to start our complete example. So, let's say we have a Rails application for a super simple blog:
# 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
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
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
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.
Here are examples of requests – based on those sample controllers – and their respective JSON responses.
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"
}
}
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"
}
}
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"
}
}
}
}
}
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"
}
}
]
}
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"
}
]
}
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"
}
}
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.
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.
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