API: Endpoint to get an organization's details (#10931)
* add organizations api request spec * add organizations api controller * add organizations api show route * add show jbuilder file * fix merge conflict on routes * add organization show to api docs * update created_at to iso format * api docs add format field/cleanup
This commit is contained in:
parent
a054b3d02b
commit
c0168df2a8
5 changed files with 171 additions and 1 deletions
16
app/controllers/api/v0/organizations_controller.rb
Normal file
16
app/controllers/api/v0/organizations_controller.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
module Api
|
||||
module V0
|
||||
class OrganizationsController < ApiController
|
||||
SHOW_ATTRIBUTES_FOR_SERIALIZATION = %i[
|
||||
username name summary twitter_username github_username url
|
||||
location created_at profile_image tech_stack tag_line story
|
||||
].freeze
|
||||
private_constant :SHOW_ATTRIBUTES_FOR_SERIALIZATION
|
||||
|
||||
def show
|
||||
@organization = Organization.select(SHOW_ATTRIBUTES_FOR_SERIALIZATION)
|
||||
.find_by!(username: params[:org_username])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
18
app/views/api/v0/organizations/show.json.jbuilder
Normal file
18
app/views/api/v0/organizations/show.json.jbuilder
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
json.type_of "organization"
|
||||
|
||||
json.extract!(
|
||||
@organization,
|
||||
:username,
|
||||
:name,
|
||||
:summary,
|
||||
:twitter_username,
|
||||
:github_username,
|
||||
:url,
|
||||
:location,
|
||||
:tech_stack,
|
||||
:tag_line,
|
||||
:story,
|
||||
)
|
||||
|
||||
json.joined_at utc_iso_timestamp(@organization.created_at)
|
||||
json.profile_image Images::Profile.call(@organization.profile_image_url, length: 640)
|
||||
|
|
@ -197,6 +197,11 @@ Rails.application.routes.draw do
|
|||
end
|
||||
|
||||
resources :profile_images, only: %i[show], param: :username
|
||||
resources :organizations, only: [] do
|
||||
collection do
|
||||
get "/:org_username", to: "organizations#show"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
105
docs/api_v0.yml
105
docs/api_v0.yml
|
|
@ -17,7 +17,7 @@ info:
|
|||
Dates and date times, unless otherwise specified, must be in
|
||||
the [RFC 3339](https://tools.ietf.org/html/rfc3339) format.
|
||||
|
||||
version: "0.9.1"
|
||||
version: "0.9.2"
|
||||
termsOfService: https://dev.to/terms
|
||||
contact:
|
||||
name: DEV Team
|
||||
|
|
@ -1104,6 +1104,49 @@ components:
|
|||
type: string
|
||||
description: Profile image (90x90)
|
||||
|
||||
Organization:
|
||||
description: Organization
|
||||
type: object
|
||||
properties:
|
||||
type_of:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
summary:
|
||||
type: string
|
||||
nullable: true
|
||||
twitter_username:
|
||||
type: string
|
||||
nullable: true
|
||||
github_username:
|
||||
type: string
|
||||
nullable: true
|
||||
url:
|
||||
type: string
|
||||
format: url
|
||||
location:
|
||||
type: string
|
||||
nullable: true
|
||||
tech_stack:
|
||||
type: string
|
||||
nullable: true
|
||||
tag_line:
|
||||
type: string
|
||||
nullable: true
|
||||
story:
|
||||
type: string
|
||||
nullable: true
|
||||
joined_at:
|
||||
description: Date of joining
|
||||
type: string
|
||||
format: date-time
|
||||
profile_image:
|
||||
type: string
|
||||
description: Profile image (640x640)
|
||||
format: url
|
||||
|
||||
examples:
|
||||
ErrorBadRequest:
|
||||
value:
|
||||
|
|
@ -1667,6 +1710,22 @@ components:
|
|||
profile_image: https://res.cloudinary.com/...jpeg
|
||||
profile_image_90: https://res.cloudinary.com/...jpeg
|
||||
|
||||
Organization:
|
||||
value:
|
||||
type_of: organization
|
||||
username: ecorp
|
||||
name: E Corp
|
||||
summary: Together we can change the world, with E Corp
|
||||
twitter_username: ecorp
|
||||
github_username: ecorp
|
||||
url: https://ecorp.internet
|
||||
location: New York
|
||||
joined_at: '2019-10-24T13:41:29Z'
|
||||
tech_stack: Ruby
|
||||
tag_line:
|
||||
story:
|
||||
profile_image: https://res.cloudinary.com/...jpeg
|
||||
|
||||
tags:
|
||||
- name: articles
|
||||
description: Articles are all the posts users create on DEV
|
||||
|
|
@ -1678,6 +1737,8 @@ tags:
|
|||
description: Users can follow other users on the website
|
||||
- name: listings
|
||||
description: Listings are classified ads
|
||||
- name: organizations
|
||||
description: Users can create and join organizations
|
||||
- name: podcast-episodes
|
||||
description: Podcast episodes
|
||||
- name: readinglist
|
||||
|
|
@ -2920,6 +2981,48 @@ paths:
|
|||
source: |
|
||||
curl -H "api-key: API_KEY" https://dev.to/api/readinglist
|
||||
|
||||
/organizations/{org_username}:
|
||||
get:
|
||||
operationId: getOrganization
|
||||
summary: An organization
|
||||
description: |
|
||||
This endpoint allows the client to retrieve a single organization by their username
|
||||
tags:
|
||||
- organizations
|
||||
parameters:
|
||||
- name: org_username
|
||||
in: path
|
||||
required: true
|
||||
description: |
|
||||
Username of the organization
|
||||
schema:
|
||||
type: string
|
||||
example: "ecorp"
|
||||
responses:
|
||||
"200":
|
||||
description: An organization
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Organization"
|
||||
examples:
|
||||
user-success:
|
||||
$ref: "#/components/examples/Organization"
|
||||
"404":
|
||||
description: Resource not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/APIError"
|
||||
examples:
|
||||
user-not-found:
|
||||
$ref: "#/components/examples/ErrorNotFound"
|
||||
x-code-samples:
|
||||
- lang: Shell
|
||||
label: curl
|
||||
source: |
|
||||
curl https://dev.to/api/organizations/ecorp
|
||||
|
||||
/podcast_episodes:
|
||||
get:
|
||||
operationId: getPodcastEpisodes
|
||||
|
|
|
|||
28
spec/requests/api/v0/organizations_spec.rb
Normal file
28
spec/requests/api/v0/organizations_spec.rb
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe "Api::V0::Organizations", type: :request do
|
||||
describe "GET /api/organizations/:username" do
|
||||
let(:organization) { create(:organization) }
|
||||
|
||||
it "returns 404 if the organizations username is not found" do
|
||||
get "/api/organizations/invalid-username"
|
||||
expect(response).to have_http_status(:not_found)
|
||||
end
|
||||
|
||||
it "returns the correct json representation of the organization", :aggregate_failures do
|
||||
get "/api/organizations/#{organization.username}"
|
||||
|
||||
response_organization = response.parsed_body
|
||||
|
||||
expect(response_organization["type_of"]).to eq("organization")
|
||||
|
||||
%w[
|
||||
username name summary twitter_username github_username url location tech_stack tag_line story
|
||||
].each do |attr|
|
||||
expect(response_organization[attr]).to eq(organization.public_send(attr))
|
||||
end
|
||||
|
||||
expect(response_organization["joined_at"]).to eq(organization.created_at.utc.iso8601)
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue