Skip to content

Commit e5b54b6

Browse files
authored
Update README.md [skip ci]
Update some links and some more detail in the readme so people can get an idea of what Graphiti is about
1 parent f2a427d commit e5b54b6

File tree

1 file changed

+218
-12
lines changed

1 file changed

+218
-12
lines changed

README.md

Lines changed: 218 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,228 @@
1+
#### Graphiti
2+
13
[![CI](https://github.com/graphiti-api/graphiti/actions/workflows/ci.yml/badge.svg)](https://github.com/graphiti-api/graphiti/actions/workflows/ci.yml)
24
[![Gem Version](https://badge.fury.io/rb/graphiti.svg)](https://badge.fury.io/rb/graphiti)
35
[![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)
46
[![semantic-release: angular](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release)
57

6-
<p align="center">
7-
<a href="https://www.graphiti.dev/guides">
8-
<img " src="https://user-images.githubusercontent.com/55264/54884141-c10ada00-4e43-11e9-866b-e3c01e33a7c7.png" />
9-
</a>
10-
</p>
11-
12-
Stylish Graph APIs.
138

14-
[Website](https://www.graphiti.dev/guides/)
9+
[![discord](https://img.shields.io/badge/community-discord-8A2BE2?logo=discord)](https://discord.gg/wgqkMBsSRV)
10+
[![guides](https://img.shields.io/badge/guides-https://www.graphiti.dev-F565A5)](https://www.graphiti.dev)
11+
12+
13+
14+
<img align="right" src="https://user-images.githubusercontent.com/55264/54884141-c10ada00-4e43-11e9-866b-e3c01e33a7c7.png" alt="Graphiti logo" width="150px" />
15+
Graphiti is a resource-oriented framework that sits on top of your models (usually ActiveRecord) and exposes them via a JSON:API-compliant interface. It abstracts common concerns like serialization, filtering, sorting, pagination, and sideloading relationships, so you can build powerful APIs with minimal boilerplate. By defining resources instead of controllers and serializers, Graphiti helps you keep your API logic organized, consistent, and easy to maintain.
16+
17+
18+
#### Examples
19+
Here's an example resource from the [example app](https://github.com/graphiti-api/employee_directory/) just to give you a taste of the possibilities.
20+
21+
22+
```ruby
23+
class EmployeeResource < ApplicationResource
24+
attribute :first_name, :string
25+
attribute :last_name, :string
26+
attribute :age, :integer
27+
attribute :created_at, :datetime, writable: false
28+
attribute :updated_at, :datetime, writable: false
29+
attribute :title, :string, only: [:filterable, :sortable]
30+
31+
has_many :positions
32+
has_many :tasks
33+
many_to_many :teams
34+
polymorphic_has_many :notes, as: :notable
35+
has_one :current_position, resource: PositionResource do
36+
params do |hash|
37+
hash[:filter][:current] = true
38+
end
39+
end
40+
41+
filter :title, only: [:eq] do
42+
eq do |scope, value|
43+
scope.joins(:current_position).merge(Position.where(title: value))
44+
end
45+
end
46+
47+
sort :title do |scope, value|
48+
scope.joins(:current_position).merge(Position.order(title: value))
49+
end
50+
51+
sort :department_name, :string do |scope, value|
52+
scope.joins(current_position: :department)
53+
.merge(Department.order(name: value))
54+
end
55+
end
56+
```
57+
58+
A pretty boilerplate controller that just interfaces with the resource
59+
```ruby
60+
class EmployeesController < ApplicationController
61+
def index
62+
employees = EmployeeResource.all(params)
63+
respond_with(employees)
64+
end
65+
66+
def show
67+
employee = EmployeeResource.find(params)
68+
respond_with(employee)
69+
end
70+
71+
def create
72+
employee = EmployeeResource.build(params)
73+
74+
if employee.save
75+
render jsonapi: employee, status: 201
76+
else
77+
render jsonapi_errors: employee
78+
end
79+
end
80+
81+
def update
82+
employee = EmployeeResource.find(params)
83+
84+
if employee.update_attributes
85+
render jsonapi: employee
86+
else
87+
render jsonapi_errors: employee
88+
end
89+
end
90+
91+
def destroy
92+
employee = EmployeeResource.find(params)
93+
94+
if employee.destroy
95+
render jsonapi: { meta: {} }, status: 200
96+
else
97+
render jsonapi_errors: employee
98+
end
99+
end
100+
end
101+
```
102+
103+
</details>
104+
105+
106+
Now you can query your endpoints simply and powerfully, like:
107+
108+
109+
110+
Request:
111+
```http://localhost:3000/api/v1/employees?filter[title][eq]=Future Government Administrator&filter[age][lt]=40```
112+
113+
<details>
114+
<summary>JSON-API response</summary>
115+
116+
```json
117+
{
118+
"data": [
119+
{
120+
"id": "1",
121+
"type": "employees",
122+
"attributes": {
123+
"first_name": "Quinn",
124+
"last_name": "Homenick",
125+
"age": 36,
126+
"created_at": "2025-03-21T23:04:40+00:00",
127+
"updated_at": "2025-03-21T23:04:40+00:00"
128+
},
129+
"relationships": {
130+
"positions": {
131+
"links": {
132+
"related": "/api/v1/positions?filter[employee_id]=1"
133+
},
134+
"data": [
135+
{
136+
"type": "positions",
137+
"id": "1"
138+
},
139+
{
140+
"type": "positions",
141+
"id": "2"
142+
}
143+
]
144+
},
145+
"tasks": {
146+
"links": {
147+
"related": "/api/v1/tasks?filter[employee_id]=1"
148+
}
149+
},
150+
"teams": {
151+
"links": {
152+
"related": "/api/v1/teams?filter[employee_id]=1"
153+
}
154+
},
155+
"notes": {
156+
"links": {
157+
"related": "/api/v1/notes?filter[notable_id]=1&filter[notable_type][eql]=Employee"
158+
}
159+
},
160+
"current_position": {
161+
"links": {
162+
"related": "/api/v1/positions?filter[current]=true&filter[employee_id]=1"
163+
},
164+
"data": {
165+
"type": "positions",
166+
"id": "1"
167+
}
168+
}
169+
}
170+
}
171+
],
172+
"included": [
173+
{
174+
"id": "1",
175+
"type": "positions",
176+
"attributes": {
177+
"title": "Future Government Administrator",
178+
"active": true
179+
},
180+
"relationships": {
181+
"employee": {
182+
"links": {
183+
"related": "/api/v1/employees/1"
184+
}
185+
},
186+
"department": {
187+
"links": {
188+
"related": "/api/v1/departments/3"
189+
}
190+
}
191+
}
192+
},
193+
{
194+
"id": "2",
195+
"type": "positions",
196+
"attributes": {
197+
"title": "Manufacturing Specialist",
198+
"active": false
199+
},
200+
"relationships": {
201+
"employee": {
202+
"links": {
203+
"related": "/api/v1/employees/1"
204+
}
205+
},
206+
"department": {
207+
"links": {
208+
"related": "/api/v1/departments/2"
209+
}
210+
}
211+
}
212+
}
213+
],
214+
"meta": {}
215+
}
216+
```
217+
218+
</details>
219+
220+
221+
222+
[Graphiti Guides](https://www.graphiti.dev/guides/)
223+
224+
[Join the Discord](https://discord.gg/wgqkMBsSRV)
15225

16-
[Join the Slack Channel](https://join.slack.com/t/graphiti-api/shared_invite/enQtMjkyMTA3MDgxNTQzLTU5MDI4MDllNTEzOTE1Nzk0ZGJlNTcxZDYzMGY2ZTczMDY2OWZhM2RmNTU0YWNiOWZhZDhkMmU4MzQ5NzIyNWM)
17226

18-
Direct Contact: [email protected]
19227

20-
Supports Rails >= 4.1
21228

22-
*Looking for JSONAPI-Suite? You're in the right place. Graphiti is the 1.0 version of JSONAPI Suite. For the deprecated Suite gem, go [here](https://github.com/jsonapi-suite/jsonapi_suite_deprecated)*

0 commit comments

Comments
 (0)