Contributors: Gavin Carew | Jedeo Manirikumwenatwe | Noah van Ekdom | Colby Pearce | Anna Marie Sterling | Catalyst | Ken Lenhart
A rails backend API for Squeakr, a short-form messaging service built around healthy conversations and robust moderation.
Squeakr uses a service-oriented architecture with a React frontend.
Check out the the front-end repo
Squeakr was built with test-driven development, with Rspec used for testing. It is built with Rails conventions over configuration as a guiding principle. A service-facade design pattern is used when calling external API services.
The backend is designed with GraphQL best practices in mind for ultimate flexibility in access. Detailed information about GraphQL queries available can be found in the Endpoints section.
Live endpoints can be found by sending a POST
request to https://squeakr-be.fly.dev/graphql/
.
Instructions to set up a local version of the Squeakr backend:
Fork and clone the project, then install the required gems with bundle
. A full list of gems that will be installed can be found in the gemfile.
bundle install
Reset and seed the database:
rake db:{drop,create,migrate,seed}
Squeakr uses Google's Perspective API to assist with content moderation. It also uses a custom Nyckel ML API that you will need to set up separately.
Once you have your keys, set up your environment with
bundle exec figaro install
Then add your keys to config/application.yml
:
MODERATION_ID: <YOUR_NYCKEL_FUNCTION_ID>
PERSPECTIVE_KEY: <YOUR_PERSPECTIVE_KEY>
Start a rails server, and you're ready to query
rails s
All endpoints can be accessed with a POST
request to the base url https://squeakr-be.fly.dev/graphql/
in production. The header Content-Type
with a value of application/json
is required for all queries and mutations. The query (or mutation) should be sent in the body of the request.
Returns all users.
Fields | Description | Data type |
---|---|---|
id | Primary key | String |
username | ~ | String |
isAdmin | Does the user have admin privileges? | Boolean |
createdAt | ~ | DateTime |
updatedAt | ~ | DateTime |
Sample query
query {
fetchUsers {
id
username
isAdmin
createdAt
updatedAt
}
}
Sample response (status 200)
"data": {
"fetchUsers": [
{
"id": "6",
"username": "realgooduser",
"isAdmin": false,
"createdAt": "2022-12-06T00:26:51Z",
"updatedAt": "2022-12-06T00:26:51Z"
},
{
"id": "5",
"username": "User 5",
"isAdmin": false,
"createdAt": "2022-12-05T22:58:28Z",
"updatedAt": "2022-12-05T22:58:28Z"
},
...
]
}
Returns a single user by their user ID.
Parameter | Description | Data type |
---|---|---|
id | Primary key | String |
Fields | Description | Data type |
---|---|---|
id | Primary key | String |
username | ~ | String |
isAdmin | Does the user have admin privileges? | Boolean |
createdAt | ~ | DateTime |
updatedAt | ~ | DateTime |
Sample mutation
query {
fetchUser(id: "4") {
id
username
isAdmin
}
}
Sample response (status 200)
{
"data": {
"fetchUser": {
"id": "4",
"username": "User 4",
"isAdmin": false
}
}
}
Add a user to the database.
Parameter | Description | Data type |
---|---|---|
username | Username must be unique | String |
isAdmin | Does the user have admin privileges? | Boolean |
Fields | Description | Data type |
---|---|---|
id | Primary key | String |
username | ~ | String |
isAdmin | Does the user have admin privileges? | Boolean |
createdAt | ~ | DateTime |
updatedAt | ~ | DateTime |
Sample query
mutation {
addUser(input: { params: { username: "Test_User", isAdmin: false } }) {
user {
id
username
isAdmin
}
}
}
Sample response (status 201)
{
"data": {
"addUser": {
"user": {
"id": "7",
"username": "Test_User",
"isAdmin": false
}
}
}
}
Returns all squeaks in the database.
Fields | Description | Data type |
---|---|---|
id | Primary key | String |
content | The text of the squeak | String |
reports | Number of times a squeak has been reported | Integer |
nuts | Number of 'nuts' (likes) | Integer |
approved | Whether a squeak has been approved by a moderator | Boolean |
user | The user who created the squeak | User |
createdAt | ~ | DateTime |
Note on approved
: Default approved status is null. When a squeak is explicitly approved by an admin, it will be true. If an admin rejects a reported squeak for objectionable content, approved will be false
Sample query
query {
allSqueaks {
id
content
reports
nuts
approved
user {
id
username
}
createdAt
}
}
Sample response (status 200)
{
"data": {
"allSqueaks": [
{
"id": "8",
"content": "Did you hear about the situation in politics?",
"reports": 0,
"nuts": 75,
"approved": null,
"user": {
"username": "User 1"
},
"createdAt": "2022-12-05T23:12:13Z"
},
{
"id": "7",
"content": "The sports team was good in the last contest",
"reports": 1,
"nuts": 8,
"approved": true,
"user": {
"username": "User 1"
},
"createdAt": "2022-12-05T23:12:13Z"
},
...
]
}
}
Returns reported squeaks in the database.
Fields | Description | Data type |
---|---|---|
id | Primary key | String |
content | The text of the squeak | String |
reports | Number of times a squeak has been reported | Integer |
nuts | Number of 'nuts' (likes) | Integer |
approved | Whether a squeak has been approved by a moderator | Boolean |
score | Probability of squeak containing identity attack | Score |
user | The user who created the squeak | User |
createdAt | ~ | DateTime |
Sample query
query {
reportedSqueaks {
id
content
reports
nuts
approved
score
user {
id
username
}
createdAt
}
}
Sample response (status 200)
{
"data": {
"reportedSqueaks": [
{
"id": "61",
"content": "Random squeak",
"reports": 1,
"nuts": 0,
"approved": null,
"score": {
"metric": "IDENTITY_ATTACK",
"probability": 0.0052906936
},
"user": {
"username": "User 2"
},
"createdAt": "2022-12-07T21:59:24Z"
},
...
]
}
}
Delete a squeak by ID.
Parameter | Description | Data type |
---|---|---|
id | Squeak primary key (required) | String |
Fields | Description | Data type |
---|---|---|
id | Primary key | String |
content | The text of the squeak | String |
reports | Number of times a squeak has been reported | Integer |
nuts | Number of 'nuts' (likes) | Integer |
approved | Whether a squeak has been approved by a moderator | Boolean |
user | ID of the user who created the squeak | Integer |
createdAt | ~ | DateTime |
Sample mutation
mutation {
deleteSqueak(input: {id: 7 }) {
squeak {
id
content
}
}
}
Sample response (status 200)
{
"data": {
"deleteSqueak": {
"squeak": {
"id": "3",
"content": "I sure hope this squeak stays up forever"
}
}
}
}
Add a squeak.
Parameter | Description | Data type |
---|---|---|
content | Squeak message content (required) | String |
user_id | Squeak message content (required) | ID |
approved | Whether a squeak has been approved by a moderator | Boolean |
Fields | Description | Data type |
---|---|---|
id | Primary key | String |
content | The text of the squeak | String |
reports | Number of times a squeak has been reported | Integer |
nuts | Number of 'nuts' (likes) | Integer |
approved | Whether a squeak has been approved by a moderator | Boolean |
user | ID of the user who created the squeak | Integer |
createdAt | ~ | DateTime |
Sample mutation
mutation {
addSqueak(input: {params: { content: "Birds are not real.", userId: "1"} }) {
squeak {
id
content
user {
id
username
isAdmin
}
}
}
}
Sample response (status 200)
{
"data": {
"addSqueak": {
"squeak": {
"id": "10",
"content": "Birds are not real."
"user": {
"id": "1",
"username": "A real good user",
"isAdmin": false
}
}
}
}
}
Update a squeak by ID.
Parameter | Description | Data type | Required |
---|---|---|---|
id | Squeak primary key (required) | String | True |
report | Report argument | Boolean | False |
nut | Nut argument | Boolean | False |
approved | Whether a squeak has been approved by a moderator | Boolean | False |
Fields | Description | Data type |
---|---|---|
id | Primary key | String |
content | The text of the squeak | String |
reports | Number of times a squeak has been reported | Integer |
nuts | Number of 'nuts' (likes) | Integer |
approved | Whether a squeak has been approved by a moderator | Boolean |
user | ID of the user who created the squeak | Integer |
createdAt | ~ | DateTime |
Sample mutation(Report)
mutation {
updateSqueak(input: {id: 7, report: true }) {
squeak {
id
content
reports
}
}
}
Sample response (report) (status 200)
{
"data": {
"updateSqueak": {
"squeak": {
"id": "3",
"content": "I sure hope this squeak stays up forever",
"reports": 1
}
}
}
}
Sample mutation(Nut)
mutation {
updateSqueak(input: {id: 7, nut: true }) {
squeak {
id
content
nuts
}
}
}
Sample response (Nut) (status 200)
{
"data": {
"updateSqueak": {
"squeak": {
"id": "3",
"content": "I sure hope this squeak stays up forever",
"nuts": 1
}
}
}
}
Sample mutation (Approved)
mutation {
updateSqueak(input: {id: 7, approved: true }) {
squeak {
id
content
approved
reports
}
}
}
Sample response (Approved) (status 200)
{
"data": {
"updateSqueak": {
"squeak": {
"id": "7",
"content": "This is squeak #6",
"approved": true,
"reports": 0
}
}
}
}