Unrated-Limited-Unlimited / ua-backend

4 stars 0 forks source link

Unrated Application - Backend

Welcome to the backend repository for Unrated, a whiskey rating application developed by Unrated Limited Unlimited Ltd.

The backend tries to offer a robust platform for whiskey enthusiasts to review, and discover whiskeys based on a wide range of criteria.

The backend is being hosted at:

https://api.unrated.no/

Technologies

Requirements

Installation

  1. Clone the repository:

    git clone https://github.com/Unrated-Limited-Unlimited/ua-backend.git
    cd ua-backend
  2. Build the project:

    ./gradlew build
  3. Run the application:

    ./gradlew run

Usage

The backend application can then be accessed via:

GraphQL Schema

Refer to schema.graphqls file in src/main/resources/ for the full GraphQL schema, which includes definitions for queries, mutations, types, and inputs required for interacting with the application. Or use the playground as stated above.

API Endpoints

See OpenAPI documentation for further details. Overview:

Example GraphQL Queries

Here are some example GraphQL queries and mutations:

# Retrieve a list of all whiskey ratings by a specific user
query {
    getUser(name: "Jeff") {
      ratings {
        title
        body
        score
      }
    }
}
# Create a new user and return id, name and email
mutation {
  createUser(user: {
    name: "NewUser",
    email: "newuser@example.com",
    password: "SecureNP#x&t@4S2Password#!"
  }) {
    id
    name
    email
  }
}

Implementation Overview

JPA classes

jpaUnrated.png

JWT Security

We use JWT tokens for authentication. JWT tokens are stateless and are returned as set-cookie on /login. Bearer JWT tokens are also accepted.

Graphql

All the mutations and query functions are first defined in schema.graphqls. The schema is parsed in GraphQLFactory, where the definitions are linked to different fetcher functions. The fetcher functions return different Jpa model objects, were the DataFetcher maps every field value of the object, to the return type of the query/mutation function defined in the schema.

Example:

  1. getWhiskey(id: ID!) : Whiskey is first defined in schema.graphqls.
  2. It is then mapped to the fetcher function WhiskeyFetcher::getWhiskey() inside GraphQLFactory.
  3. The fetcher function is called on request call, and returns a DataFetcher<Whiskey>.
  4. The DataFetcher returns all fields of the Jpa Whiskey object that are also present in the schema.
    • (This makes it so UserData.password won't be serialized, since type UserData in schema.graphqls does not have a field called password for type UserData.)