### Rails API Installation with Graphiti Template Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/quickstart.html This command installs Graphiti and sets up a new Rails API application using a provided template. It handles gem installations and module inclusions to configure the project for Graphiti. Users can accept defaults for a quick setup. ```bash rails new blog --api -m https://www.graphiti.dev/template ``` -------------------------------- ### Define a Simple Graphiti Resource (Ruby) Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/guides/getting-started/installation.md Example of defining a basic Graphiti Resource for a Post model, specifying the adapter and attributes. It demonstrates how to retrieve all data for the resource. ```ruby # Assuming you already have a Post ActiveRecord Model class PostResource < Graphiti::Resource self.adapter = Graphiti::Adapters::ActiveRecord attribute :title, :string end PostResource.all.data # => [#, #, ...] ``` -------------------------------- ### Install Graphiti API from Scratch (Bash) Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/guides/getting-started/installation.md Command to create a new Rails API project with Graphiti pre-installed using a remote template. Alternatively, download the template locally and use it. ```bash rails new blog --api -m https://raw.githubusercontent.com/graphiti-api/graphiti_rails_template/master/all.rb ``` ```bash curl -O https://raw.githubusercontent.com/graphiti-api/graphiti_rails_template/master/all.rb rails new blog --api -m all.rb ``` -------------------------------- ### Graphiti Configuration File Example (.graphiticfg.yml) Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/guides/getting-started/installation.html An example of the .graphiticfg.yml file, which is placed in the root of the application. It is used to store reusable configuration, such as the API namespace. ```yaml --- namespace: /my_api/v1 ``` -------------------------------- ### Start Rails Server Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/quickstart.html This command starts the Rails development server, making the API accessible for testing. After running this, the API endpoints defined by Graphiti, such as http://localhost:3000/api/v1/posts, should be available. ```bash bundle exec rails s ``` -------------------------------- ### Install RSpec for Graphiti API Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/guides/getting-started/installation.md This command installs RSpec, a testing framework, into a Rails project. It generates the necessary configuration files for RSpec to work within the application. ```bash bin/rails g rspec:install ``` -------------------------------- ### Error Handling Example Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/quickstart.md Illustrates how the API returns JSONAPI-compliant error responses, including a sample payload for an unexpected error. ```APIDOC ## Error Handling ### Description The API returns JSONAPI-compliant error responses for various issues. ### Method N/A (Demonstrates error response) ### Endpoint N/A (Demonstrates error response) ### Response #### Error Response (e.g., 500) - **errors** (array) - An array of error objects, each detailing an issue. - **id** (string) - A unique identifier for the error. - **links** (object) - Links related to the error. - **status** (string) - The HTTP status code. - **code** (string) - An application-specific error code. - **title** (string) - A short, human-readable summary of the problem. - **detail** (string) - A human-readable explanation specific to this occurrence of the problem. - **source** (object) - An object containing references to the source of the error. - **meta** (object) - A meta object containing non-standard meta-information about the error. ### Response Example (Internal Server Error) ```json { "errors": [ { "id": "a1b2c3d4-e5f6-7890-1234-567890abcdef", "status": "500", "code": "INTERNAL_SERVER_ERROR", "title": "An unexpected error occurred.", "detail": "Something went wrong on our end." } ] } ``` ``` -------------------------------- ### Integrate Responders Gem with Graphiti (Ruby) Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/guides/getting-started/installation.md Shows how to use the 'responders' gem to simplify response handling in Rails controllers when working with Graphiti. It also details the necessary Gemfile addition and controller inclusion. ```ruby # Gemfile gem 'responders' # app/controllers/application_controller.rb include Graphiti::Responders ``` ```ruby def index posts = PostResource.all(params) respond_with(posts) end ``` -------------------------------- ### Reset and Seed Database (Bash) Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/quickstart.md Commands to reset the database to its initial state and then seed it with new data. This is typically done before running the application to ensure a clean state for testing or initial setup. ```bash $ bundle exec rails db:migrate:reset ``` ```bash $ bundle exec rails db:seed ``` -------------------------------- ### Graphiti Rails Setup Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/guides/concepts/error-handling.md Provides the basic Ruby gem installation command for `graphiti-rails`, which is a prerequisite for implementing advanced error handling features in Rails applications using Graphiti. ```ruby gem 'graphiti-rails' ``` -------------------------------- ### Defining Models and Connecting to API Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/js/installation.md Guide on how to define models in Spraypaint, including setting the base URL, API namespace, and JSON:API type. ```APIDOC ## Defining Models ### Connecting to the API Just like `ActiveRecord`, our models will inherit from a base class that holds connection information (`ApplicationRecord`, or `ActiveRecord::Base` in Rails < 5): ```typescript @Model() class ApplicationRecord extends SpraypaintBase { static baseUrl = "http://my-api.com" static apiNamespace = "/api/v1" } ``` ```javascript const ApplicationRecord = SpraypaintBase.extend({ static: { baseUrl: "http://my-api.com", apiNamespace: "/api/v1" } }) ``` All URLs follow the following pattern: * `baseUrl` + `apiNamespace` + `jsonapiType` As you can see above, typically `baseUrl` and `apiNamespace` are set on a top-level `ApplicationRecord` (though any subclass can override). `jsonapiType`, however, is set per-model: ```typescript @Model() class Person extends ApplicationRecord { static jsonapiType = "people" } ``` ```javascript const Person = ApplicationRecord.extend({ static: { jsonapiType: "people" } }) ``` With the above configuration, all `Person` endpoints will begin `http://my-api.com/api/v1/people`. > **TIP**: Avoid CORS and use relative paths by simply setting `baseUrl` to `""` > **TIP**: You can always use the `endpoint` option to override this pattern and set the endpoint manually. ##### Setting Application Name It can be helpful to send the name of your client application in request headers. With this information, servers can keep track of which clients are hitting which APIs. To do this: ```typescript @Model() class Person extends ApplicationRecord { static clientApplication = "sales-backend" } ``` ```javascript const Person = ApplicationRecord.extend({ static: { clientApplication: "sales-backend" } }) ``` ``` -------------------------------- ### Install Spraypaint and isomorphic-fetch Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/js/installation.html Instructions for installing the Spraypaint ORM and the isomorphic-fetch library using either yarn or npm. These are common dependencies for client-side API interactions. ```bash $ yarn add spraypaint isomorphic-fetch ``` ```bash $ npm install spraypaint isomorphic-fetch ``` -------------------------------- ### Perform Resource Creation Request in Ruby Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/quickstart.md Shows a Ruby RSpec example for creating a new employee resource via a JSONAPI POST request. It includes defining the payload and asserting the expected outcomes like resource build, count change, and response status. ```ruby subject(:make_request) do jsonapi_post "/api/v1/employees", payload end describe 'basic create' do let(:payload) do { data: { type: 'employees', attributes: { first_name: 'Jane' } } } end it 'works' do expect(EmployeeResource).to receive(:build).and_call_original expect { make_request }.to change { Employee.count }.by(1) expect(response.status).to eq(201) end end ``` -------------------------------- ### Installation Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/js/installation.md Instructions on how to install Spraypaint and its dependencies using yarn or npm. ```APIDOC ## Installation Installation is straightforward. Since we use `fetch` underneath the hood, we recommend installing alongside a `fetch` polyfill. If using `yarn`: ```bash $ yarn add spraypaint isomorphic-fetch ``` If using `npm`: ```bash $ npm install spraypaint isomorphic-fetch ``` Now import it: ```typescript import { Model, SpraypaintBase, Attr, BelongsTo, HasMany // etc } from "spraypaint" ``` ```javascript const { SpraypaintBase, attr, belongsTo, hasMany // etc } = require("spraypaint/dist/spraypaint") ``` ...or, if you're avoiding JS modules, `spraypaint` will be available as a global in the browser. ``` -------------------------------- ### Register Graphiti Exception Handling (Ruby) Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/guides/getting-started/installation.md Configures Graphiti to handle specific exceptions, such as RecordNotFound, by returning a 404 status code. It also sets up a general exception handler for other errors. ```ruby # app/controllers/application_controller.rb # When #show action does not find record, return 404 register_exception Graphiti::Errors::RecordNotFound, status: 404 rescue_from Exception do |e| handle_exception(e) end ``` -------------------------------- ### Seeding Data Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/quickstart.html Instructions on how to seed initial data into the database using a Ruby script. ```APIDOC ## Seeding Data ### Description This section describes how to populate the database with initial data using a Ruby script. ### Steps 1. **Edit `db/seeds.rb`**: Add `Post.create!` calls to define the initial posts. ```ruby Post.create!(title: 'My title', upvotes: 10, active: true) Post.create!(title: 'Another title', upvotes: 20, active: false) Post.create!(title: 'OMG! A title', upvotes: 30, active: true) ``` 2. **Run the seed script**: Execute the following command in your terminal: ```bash $ bundle exec rails db:seed ``` 3. **Verify data**: Access `http://localhost:3000/api/v1/posts` to confirm the posts have been added. ``` -------------------------------- ### GET /api/v1/posts?include=comments Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/quickstart.html Retrieves a list of posts and includes associated comments through eager-loading. ```APIDOC ## GET /api/v1/posts?include=comments ### Description Retrieves a list of posts and includes their associated comments via eager-loading. ### Method GET ### Endpoint /api/v1/posts ### Parameters #### Query Parameters - **include** (string) - Optional - Specifies relationships to eager-load. Use 'comments' to include comments. ### Request Example ```json { "request": "GET /api/v1/posts?include=comments" } ``` ### Response #### Success Response (200) - **data** (array) - A list of posts, with associated comments included. #### Response Example ```json { "data": [ { "type": "posts", "id": "1", "attributes": { "title": "Example Post" }, "relationships": { "comments": { "data": [ { "type": "comments", "id": "1" }, { "type": "comments", "id": "2" } ] } } } ], "included": [ { "type": "comments", "id": "1", "attributes": { "body": "Great post!", "active": true }, "relationships": { "post": { "data": { "type": "posts", "id": "1" } } } }, { "type": "comments", "id": "2", "attributes": { "body": "Very informative.", "active": true }, "relationships": { "post": { "data": { "type": "posts", "id": "1" } } } } ] } ``` ``` -------------------------------- ### GET /api/v1/posts - Retrieving Posts Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/quickstart.html Retrieve a list of posts with various query capabilities including sorting, pagination, sparse fieldsets, filtering, extra fields, and statistics. ```APIDOC ## GET /api/v1/posts ### Description Retrieve a list of posts. Supports sorting, pagination, sparse fieldsets, filtering, extra fields, and statistics. ### Method GET ### Endpoint /api/v1/posts ### Query Parameters - **sort** (string) - Optional - Specifies the field to sort by. Prepend with '-' for descending order (e.g., `sort=title` or `sort=-title`). - **page[size]** (integer) - Optional - Sets the number of items per page for pagination. - **page[number]** (integer) - Optional - Specifies the page number for pagination. - **fields[posts]** (string) - Optional - Comma-separated list of fields to include for the 'posts' resource (e.g., `fields[posts]=title`). - **filter[field]** (string) - Optional - Filters results based on a specific field. Supports various operators like `eql`, `prefix`, `suffix`, `match`, `gt`, `gte`, `lt`, `lte` (e.g., `filter[title]=my title`, `filter[upvotes][gt]=20`). - **extra_fields[posts]** (string) - Optional - Comma-separated list of extra fields to include for the 'posts' resource (e.g., `extra_fields[posts]=description`). - **stats[total]** (string) - Optional - Requests statistics, such as `count`, for the resource. ### Request Example ```json { "example": "GET /api/v1/posts?sort=-title&page[size]=2&page[number]=2&filter[upvotes][gt]=20&extra_fields[posts]=description&stats[total]=count" } ``` ### Response #### Success Response (200) - **data** (array) - An array of post objects. - **links** (object) - Pagination links. - **meta** (object) - Contains statistics if requested. #### Response Example ```json { "data": [ { "type": "posts", "id": "1", "attributes": { "title": "Another title", "upvotes": 20, "active": false, "description": "Inactive Post" } } ], "links": { "self": "/api/v1/posts?sort=-title&page[size]=2&page[number]=2&filter[upvotes][gt]=20&extra_fields[posts]=description", "first": "/api/v1/posts?sort=-title&page[size]=2&filter[upvotes][gt]=20&extra_fields[posts]=description", "prev": "/api/v1/posts?sort=-title&page[size]=2&page[number]=1&filter[upvotes][gt]=20&extra_fields[posts]=description", "next": "/api/v1/posts?sort=-title&page[size]=2&page[number]=3&filter[upvotes][gt]=20&extra_fields[posts]=description", "last": "/api/v1/posts?sort=-title&page[size]=2&page[number]=1&filter[upvotes][gt]=20&extra_fields[posts]=description" }, "meta": { "total": 3 } } ``` #### Error Response (e.g., 500) - **errors** (array) - An array of error objects describing the issue. #### Error Response Example ```json { "errors": [ { "status": "500", "title": "Internal Server Error", "detail": "An unexpected error occurred." } ] } ``` ``` -------------------------------- ### Add Graphiti and Kaminari Gems to Rails Project (Ruby) Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/guides/getting-started/installation.md Adds the necessary Graphiti gem for API functionality and the Kaminari gem for automatic ActiveRecord pagination to a Rails application's Gemfile. Test-specific gems are also included. ```ruby # The only strictly-required gem gem 'graphiti' # For automatic ActiveRecord pagination gem 'kaminari' # Test-specific gems group :development, :test do gem 'rspec-rails' gem 'factory_bot_rails' gem 'faker' gem 'graphiti_spec_helpers' end group :test do gem 'database_cleaner' end ``` -------------------------------- ### Fetch Posts with Included Comments via API Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/quickstart.html This example shows how to make an API request to retrieve a `Post` and its associated `Comment`s in a single request using the `include` parameter. This leverages Graphiti's ability to eager-load relationships. ```http /api/v1/posts?include=comments ``` -------------------------------- ### Include Graphiti::Rails in Application Controller (Ruby) Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/guides/getting-started/installation.md Integrates Graphiti functionality into the Rails application by including the Graphiti::Rails module in the ApplicationController. This enables Graphiti features within controllers. ```ruby # app/controllers/application_controller.rb class ApplicationController < ActionController::Base include Graphiti::Rails end ``` -------------------------------- ### Persisting Data (Create, Update, Delete) Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/quickstart.html Overview of how to persist data through the API, including creating, updating, and deleting resources. ```APIDOC ## Persisting Data ### Description Resources can be created, updated, and deleted via the API. Multiple resources can be persisted in a single request. ### Observation The best way to understand the persistence behavior is to examine the generated test files, such as `spec/api/v1/employees/create_spec.rb`. ``` -------------------------------- ### Graphiti API Request Examples (JSONAPI, Simple JSON, XML) Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/guides/overview.html Illustrates how to request data from a Graphiti API in different formats. This includes standard JSONAPI, a simpler JSON format, and XML. These examples show the base URLs for accessing the employee resource. ```http /employees.jsonapi /employees.json /employees.xml ``` -------------------------------- ### Configure Graphiti Exception Handling Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/guides/getting-started/installation.html Sets up custom exception handling for Graphiti, specifically registering a 404 status for Graphiti::Errors::RecordNotFound and a general handler for other exceptions. ```ruby register_exception Graphiti::Errors::RecordNotFound, status: 404 rescue_from Exception do |e| handle_exception(e) end ``` -------------------------------- ### Configure RSpec with Graphiti Spec Helpers in Ruby Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/guides/getting-started/installation.md This Ruby code configures RSpec to integrate with Graphiti spec helpers, FactoryBot, and DatabaseCleaner. It sets up methods for testing API resources and manages database state between test runs to ensure test isolation. ```ruby require 'graphiti_spec_helpers/rspec' RSpec.configure do |config| config.include FactoryBot::Syntax::Methods config.include GraphitiSpecHelpers::RSpec config.include GraphitiSpecHelpers::Sugar # Raise errors during tests by default config.before :each do GraphitiErrors.disable! end # Clean your DB between test runs config.before(:suite) do DatabaseCleaner.strategy = :transaction DatabaseCleaner.clean_with(:truncation) end config.around(:each) do |example| begin DatabaseCleaner.cleaning do example.run end ensure DatabaseCleaner.clean end end end ``` -------------------------------- ### Customize Graphiti Pagination with will_paginate Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/guides/getting-started/installation.html This example demonstrates how to customize Graphiti's pagination behavior when using the 'will_paginate' gem instead of the default Kaminari. It shows how to override the default pagination method in ApplicationResource. ```ruby # app/resources/application_resource.rb paginate do |scope, current_page, per_page| scope.paginate(page: current_page, per_page: per_page) end ``` -------------------------------- ### Define a Graphiti Resource (ActiveRecord) Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/guides/getting-started/installation.html Demonstrates how to define a basic Graphiti Resource for a Post model using the ActiveRecord adapter. It specifies the attributes and their types. ```ruby class PostResource < Graphiti::Resource self.adapter = Graphiti::Adapters::ActiveRecord attribute :title, :string end ``` -------------------------------- ### Vandal UI Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/quickstart.html Information on accessing and using the Vandal UI for API exploration. ```APIDOC ## Vandal UI ### Description Vandal is a UI tool that introspects your API schema, allowing for easy data exploration and querying. ### Access Navigate to `http://localhost:3000/api/v1/vandal` (or the relevant endpoint for your application) to access the Vandal interface. ### Usage - Click on a relationship to include it in the response. - Click a second time on an included relationship to edit deep query logic for the associated Resource. - If an association is included, clicking a table row allows viewing associated data. ### Example Use Case Fetching posts and comments, including only comments with the text "two": `/posts?include=comments&filter[comments.body]=two` ### Links - Interactive Vandal instance (Employee Directory Tutorial): [https://jsonapi-employee-directory.herokuapp.com/vandal](https://jsonapi-employee-directory.herokuapp.com/vandal) ``` -------------------------------- ### Includes API Examples Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/js/reads/includes.md Examples demonstrating the usage of the #includes() method for sideloading associations with Graphiti API. ```APIDOC ## Includes API Examples ### Description Demonstrates how to use the `#includes()` method to sideload associations in Graphiti API. This allows you to fetch related resources in a single request. ### Method GET ### Endpoint /posts ### Query Parameters - **include** (string or array) - Optional - Specifies the associations to include. Can be a single association, an array of associations, or an object for nested associations. ### Request Example **Single Association:** ```typescript Post.includes("comments").all() ``` **Multiple Associations:** ```typescript Post.includes(["blog", "comments"]).all() ``` **Nested Associations:** ```typescript Post.includes(["blog", { comments: "author" }]).all() ``` ### Response #### Success Response (200) The response will contain the primary resources along with their associated resources, as specified by the `include` parameter. #### Response Example *(Response structure depends on the specific associations included and the API's JSON:API compliance.)* **Example for `/posts?include=comments`:** ```json { "data": [ { "type": "posts", "id": "1", "attributes": { ... }, "relationships": { "comments": { "links": { "related": "/posts/1/comments" } } } } ], "included": [ { "type": "comments", "id": "101", "attributes": { ... } }, { "type": "comments", "id": "102", "attributes": { ... } } ] } ``` **Example for `/posts?include=blog,comments.author`:** ```json { "data": [ { "type": "posts", "id": "1", "attributes": { ... }, "relationships": { "blog": { "links": { "related": "/posts/1/blog" } }, "comments": { "links": { "related": "/posts/1/comments" } } } } ], "included": [ { "type": "blogs", "id": "5", "attributes": { ... } }, { "type": "comments", "id": "101", "attributes": { ... }, "relationships": { "author": { "links": { "related": "/comments/101/author" } } } }, { "type": "comments", "id": "102", "attributes": { ... }, "relationships": { "author": { "links": { "related": "/comments/102/author" } } } }, { "type": "authors", "id": "201", "attributes": { ... } } ] } ``` ``` -------------------------------- ### Graphiti API Sorting Examples Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/guides/overview.html Provides examples of how to sort data returned by the Graphiti API. It covers both ascending and descending order sorting using the 'sort' query parameter, with a '-' prefix indicating descending order. ```http # Ascending /employees?sort=age # Descending /employees?sort=-age ``` -------------------------------- ### POST /api/v1/employees Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/quickstart.html Creates a new employee resource. The request body should follow the JSON:API specification for data formatting. ```APIDOC ## POST /api/v1/employees ### Description Creates a new employee resource. ### Method POST ### Endpoint /api/v1/employees ### Parameters #### Request Body - **data** (object) - Required - The payload data for the employee resource. - **type** (string) - Required - Must be 'employees'. - **attributes** (object) - Required - The attributes of the employee. - **first_name** (string) - Required - The first name of the employee. ### Request Example ```json { "data": { "type": "employees", "attributes": { "first_name": "Jane" } } } ``` ### Response #### Success Response (201) - **data** (object) - The created employee resource. #### Response Example ```json { "data": { "type": "employees", "id": "1", "attributes": { "first_name": "Jane" } } } ``` ``` -------------------------------- ### Create Resource (POST /api/v1/employees) Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/quickstart.md Allows for the creation of new employee resources. This endpoint supports creating a single resource with specified attributes. ```APIDOC ## POST /api/v1/employees ### Description Creates a new employee resource. ### Method POST ### Endpoint `/api/v1/employees` ### Parameters #### Request Body - **data** (object) - Required - The resource data. - **type** (string) - Required - The type of resource, 'employees'. - **attributes** (object) - Required - The attributes of the employee. - **first_name** (string) - Required - The first name of the employee. ### Request Example ```json { "data": { "type": "employees", "attributes": { "first_name": "Jane" } } } ``` ### Response #### Success Response (201) - **data** (object) - The newly created employee resource. #### Response Example ```json { "data": { "type": "employees", "id": "1", "attributes": { "first_name": "Jane" } } } ``` ``` -------------------------------- ### Employee Resource Example Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/guides/overview.html Demonstrates a basic Employee Resource definition in Graphiti, including attributes and usage with Rails. ```APIDOC ## Employee Resource Example ### Description This example illustrates how to define an `EmployeeResource` in Graphiti, map it to a Rails `Employee` model, and utilize its features for API interactions. ### Resource Definition ```ruby # app/resources/employee_resource.rb class EmployeeResource < ApplicationResource attribute :name, :string attribute :age, :integer end ``` ### Rails Integration #### Routes ```ruby # config/routes.rb resources :employees ``` #### Controller ```ruby # app/controllers/employees_controller.rb class EmployeesController < ApplicationController def index employees = EmployeeResource.all(params) respond_with(employees) end end ``` ### API Endpoints and Features * **Format Negotiation**: Supports JSONAPI, Simple JSON, and XML. * `/employees.jsonapi` * `/employees.json` * `/employees.xml` * **Pagination**: Control the number and page of results. * `/employees?page[size]=10&page[number]=2` * **Sorting**: Order results by attribute. * Ascending: `/employees?sort=age` * Descending: `/employees?sort=-age` * **Filtering**: Filter results based on attribute values. * Case Insensitive: `/employees?filter[name]=jane doe` * Case Sensitive: `/employees?filter[name][eql]=Jane Doe` * Prefix: `/employees?filter[name][prefix]=graph` * Suffix: `/employees?filter[name][suffix]=rocks` * Contains: `/employees?filter[name][match]=iti` * Equal: `/employees?filter[age]=100` * Greater Than: `/employees?filter[age][gt]=100` * Greater Than or Equal To: `/employees?filter[age][gte]=100` * Less Than: `/employees?filter[age][lt]=100` * Less Than or Equal To: `/employees?filter[age][lte]=100` * **Field Selection**: Specify which fields to return in the response. * Example: `/employees?fields[employees]=name,age` ``` -------------------------------- ### Relationship Usage API Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/quickstart.html Demonstrates how to fetch a Post and its associated Comments with filtering and sorting capabilities. ```APIDOC ## GET /api/v1/posts ### Description Fetches a list of posts and allows eager loading of associated comments. ### Method GET ### Endpoint /api/v1/posts ### Query Parameters - **include** (string) - Optional - Specifies which associated resources to include in the response (e.g., `comments`). - **sort** (string) - Optional - Allows sorting of the results. For associated resources, use `association.field` (e.g., `-comments.created_at` for descending sort by comment creation time). - **filter[comments.active]** (boolean) - Optional - Filters comments based on their active status. ### Request Example ```json { "example": "GET /api/v1/posts?include=comments&sort=-comments.created_at&filter[comments.active]=true" } ``` ### Response #### Success Response (200) - **data** (array) - Contains the post resources. - **id** (string) - The post ID. - **type** (string) - The resource type (`posts`). - **attributes** (object) - The post attributes. - **relationships** (object) - The associated resources, such as comments. - **comments** (object) - Contains comment data if included. #### Response Example ```json { "data": [ { "id": "1", "type": "posts", "attributes": { "title": "My title!", "active": true }, "relationships": { "comments": { "data": [ { "id": "1", "type": "comments", "attributes": { "body": "comment one", "active": true } }, { "id": "3", "type": "comments", "attributes": { "body": "comment three", "active": true } } ] } } } ] } ``` ``` ```APIDOC ## GET /api/v1/comments ### Description Fetches a list of comments with filtering capabilities. ### Method GET ### Endpoint /api/v1/comments ### Query Parameters - **filter[active]** (boolean) - Optional - Filters comments based on their active status. ### Request Example ```json { "example": "GET /api/v1/comments?filter[active]=true" } ``` ### Response #### Success Response (200) - **data** (array) - Contains the comment resources. - **id** (string) - The comment ID. - **type** (string) - The resource type (`comments`). - **attributes** (object) - The comment attributes. #### Response Example ```json { "data": [ { "id": "1", "type": "comments", "attributes": { "body": "comment one", "active": true } } ] } ``` ``` -------------------------------- ### TypeScript Usage Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/js/installation.md Information on Spraypaint's TypeScript support and configuration, including how to handle strict property initialization. ```APIDOC ## Typescript Spraypaint supports Typescript versions `>= 2.8`. By default you will need a `!` after each attribute and relationship: ```typescript @Attr first_name!: string @HasMany() positions!: Position[] ``` This is due to [Strict Class Initialization](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#strict-class-initialization). For the purposes of Spraypaint, we don't need this. Remove the need for `!` (as the rest of these guides do) by setting `"strictPropertyInitialization": false` in `tsconfig.json`. ``` -------------------------------- ### Vandal UI Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/quickstart.md The Vandal UI provides a graphical interface for exploring your API schema and querying data. ```APIDOC ## Vandal UI ### Description Access the Graphiti UI for interactive API exploration. ### Method GET ### Endpoint `/api/v1/vandal` ### Usage Navigate to `http://localhost:3000/api/v1/vandal` in your browser. You can click on relationships to include them in queries and click on table rows to view associated data. Deep query logic can also be edited within the UI. ``` -------------------------------- ### Requesting Statistics Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/quickstart.md Demonstrates how to request aggregate statistics, such as the total count of posts, which are returned in the `meta` section of the response. ```APIDOC ## GET /api/v1/posts?stats[total]=count ### Description Retrieves aggregate statistics, like the total count of posts, alongside the primary data. ### Method GET ### Endpoint `/api/v1/posts` ### Parameters #### Query Parameters - **stats[total]** (string) - Required - Specifies the type of statistic to retrieve (e.g., 'count'). ### Request Example ```json { "stats": { "total": "count" } } ``` ### Response #### Success Response (200) - **meta** (object) - Contains statistical information, such as the total count. - **data** (array) - A list of posts matching any applied filters. #### Response Example ```json { "meta": { "total": 100 }, "data": [ { "type": "posts", "id": "1", "attributes": { "title": "Example Post" } } ] } ``` ``` -------------------------------- ### Integrate Graphiti with Rails Controllers Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/guides/getting-started/installation.html Includes the Graphiti::Rails module in the ApplicationController to enable Graphiti functionality within Rails endpoints. ```ruby class ApplicationController < ActionController::Base include Graphiti::Rails end ``` -------------------------------- ### Bootstrap Rails Project with Graphiti Template (Bash) Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/tutorial/step_0.md Creates a new Rails API project using a specified template URL. This command sets up the project with necessary gems and boilerplate configurations for Graphiti. ```bash $ rails new employee_directory --api -m https://www.graphiti.dev/template $ cd employee_directory ``` -------------------------------- ### Fetching Posts with Comments Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/quickstart.md This endpoint allows you to fetch posts and include their associated comments. You can also apply filtering and sorting to the comments. ```APIDOC ## GET /api/v1/posts ### Description Fetches a list of posts and allows for eager-loading of associated comments. ### Method GET ### Endpoint `/api/v1/posts` ### Query Parameters - **include** (string) - Optional - Specifies associations to include in the response (e.g., `comments`). - **sort** (string) - Optional - Specifies sorting order for included associations (e.g., `-comments.created_at`). - **filter[comments.active]** (boolean) - Optional - Filters comments based on their active status. ### Request Example ```json { "example": "/api/v1/posts?include=comments&sort=-comments.created_at&filter[comments.active]=true" } ``` ### Response #### Success Response (200) - **data** (array) - Array of post objects, potentially including comment data. - **included** (array) - Array of associated comment objects if `include` was used. #### Response Example ```json { "data": [ { "type": "posts", "id": "1", "attributes": { "title": "My title!", "active": true }, "relationships": { "comments": { "data": [ { "type": "comments", "id": "1" }, { "type": "comments", "id": "3" } ] } } } ], "included": [ { "type": "comments", "id": "1", "attributes": { "body": "comment one", "active": true } }, { "type": "comments", "id": "3", "attributes": { "body": "comment three", "active": true } } ] } ``` ``` -------------------------------- ### Create New Rails API Project with Graphiti Template Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/quickstart.md This command creates a new Rails API project and applies a template that includes necessary configurations for Graphiti. It sets up the basic structure and dependencies for using Graphiti. ```bash $ rails new blog --api -m https://www.graphiti.dev/template ``` -------------------------------- ### Graphiti Rails Installation - Bash Source: https://context7.com/graphiti-api/graphiti-api.github.io/llms.txt Provides bash commands for setting up Graphiti in a Rails application. It includes creating a new Rails API project with the Graphiti template and instructions for adding Graphiti and its dependencies to an existing Rails app. ```bash # Create new Rails API with Graphiti template rails new blog --api -m https://raw.githubusercontent.com/graphiti-api/graphiti_rails_template/master/all.rb ``` ```bash # Or add to existing Rails app - Gemfile: gem 'graphiti' gem 'kaminari' # For pagination gem 'responders' # For respond_with group :development, :test do gem 'rspec-rails' gem 'factory_bot_rails' gem 'faker' gem 'graphiti_spec_helpers' end ``` -------------------------------- ### GET /api/v1/comments Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/quickstart.html Retrieves a list of comments. This endpoint supports deep querying and filtering based on associated post IDs. ```APIDOC ## GET /api/v1/comments ### Description Retrieves a list of comments. Supports deep querying and filtering, such as filtering by the associated post's ID. ### Method GET ### Endpoint /api/v1/comments ### Parameters #### Query Parameters - **filter[post_id]** (integer) - Optional - Filters comments by the ID of the associated post. - **sort** (string) - Optional - Specifies sorting criteria for comments. ### Request Example ```json { "request": "GET /api/v1/comments?filter[post_id]=123&sort=-created_at" } ``` ### Response #### Success Response (200) - **data** (array) - A list of comment resources matching the filter and sort criteria. #### Response Example ```json { "data": [ { "type": "comments", "id": "1", "attributes": { "body": "First comment on this post.", "active": true, "post_id": 123 } }, { "type": "comments", "id": "2", "attributes": { "body": "Another comment.", "active": false, "post_id": 123 } } ] } ``` ``` -------------------------------- ### Manual Responders for Graphiti Data Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/guides/getting-started/installation.html Shows how to manually respond to different formats (JSON, JSONAPI, XML) when serving Graphiti resources. This is typically done within a controller action. ```ruby def index posts = PostResource.all(params) respond_to do |format| format.json { render(json: posts) } format.jsonapi { render(jsonapi: posts) } format.xml { render(xml: posts) } end end ``` -------------------------------- ### Import Spraypaint core components Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/js/installation.md Imports necessary components from the spraypaint library for defining models and attributes in TypeScript. This setup is for JavaScript module systems. ```typescript import { Model, SpraypaintBase, Attr, BelongsTo, HasMany // etc } from "spraypaint" ``` ```javascript const { SpraypaintBase, attr, belongsTo, hasMany // etc } = require("spraypaint/dist/spraypaint") ``` -------------------------------- ### Create New Rails App with Graphiti Template Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/guides/getting-started/installation.html Generates a new Rails API application with Graphiti pre-installed using a remote template. Alternatively, download the template locally and use it. ```bash $ rails new blog --api -m https://raw.githubusercontent.com/graphiti-api/graphiti_rails_template/master/all.rb curl -O https://raw.githubusercontent.com/graphiti-api/graphiti_rails_template/master/all.rb rails new blog --api -m all.rb ``` -------------------------------- ### Seeding Initial Posts Data in Rails Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/quickstart.html This snippet demonstrates how to seed initial 'Post' records into the database using a Ruby on Rails script. It includes creating posts with specific attributes and the command to run the seed script. After seeding, it suggests verifying the data by accessing a specific API endpoint. ```ruby Post.create!(title: 'My title', upvotes: 10, active: true) Post.create!(title: 'Another title', upvotes: 20, active: false) Post.create!(title: 'OMG! A title', upvotes: 30, active: true) ``` -------------------------------- ### RSpec Shared Context for Testing Duplication Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/guides/concepts/testing.md This example shows how to use RSpec's shared_context to avoid duplicating test setup code between model unit tests and resource integration tests. It defines shared data and includes it in both test contexts. ```ruby # spec/support/employees_helper.rb RSpec.shared_context 'employees by title' do let!(:employee1) { create(:employee) } let!(:employee2) { create(:employee) } let!(:employee3) { create(:employee) } let!(:position1) do create(:position, title: 'foo', employee: employee1) end let!(:position2) do create(:position, title: 'BAR', employee: employee2) end let!(:position3) do create(:position, title: 'bar', employee: employee3) end end # spec/models/employee.rb describe '.by_title' do include_context 'employees by title' it 'returns employees matching the given title' do expect(Employee.by_title('bar')) .to eq([employee2, employee3]) end end # spec/resources/employee_resource.rb describe 'filtering' do describe 'by title' do include_context 'employees by title' before do params[:filter] = { title: 'bar' } end it 'returns employees matching the given title' do expect(records).to eq([employee2, employee3]) end end end ``` -------------------------------- ### Creating a Post Resource in Graphiti API Tests Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/quickstart.html This snippet is part of a test file (`spec/api/v1/employees/create_spec.rb`) for the Graphiti API, demonstrating how to make a request to create a new resource. It's a placeholder for observing persistence behaviors like Create, Update, and Delete. ```ruby subject(:make_request) do ``` -------------------------------- ### Filtering Posts by Title in Graphiti API Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/quickstart.html Provides examples of filtering 'Post' resources by their 'title' attribute in the Graphiti API. It covers simple equality checks, case-insensitive comparisons, prefix, suffix, and substring matching, as well as numerical comparisons for 'upvotes'. ```http /api/v1/posts?filter[title]=my title /api/v1/posts?filter[title][eql]=My title /api/v1/posts?filter[title][prefix]=my /api/v1/posts?filter[title][suffix]=title /api/v1/posts?filter[title][match]=itl /api/v1/posts?filter[upvotes][gt]=20 /api/v1/posts?filter[upvotes][gte]=20 /api/v1/posts?filter[upvotes][lt]=20 /api/v1/posts?filter[upvotes][lte]=20 ``` -------------------------------- ### Adapters Overview Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/_site/guides/concepts/resources.html Introduces the concept of Adapters in Graphiti for packaging common resource overrides and using different data sources or clients, with a pointer to a detailed cookbook. ```APIDOC ## Adapters Overview ### Description Adapters in Graphiti allow you to package common resource overrides and logic for code re-use. They are particularly useful when working with data sources other than ActiveRecord/RelationalDB. ### Further Information Detailed explanations and examples of using Adapters, especially for non-ActiveRecord scenarios, can be found in the Graphiti Cookbook: [Adapters are best explained in our ‘Without ActiveRecord’ Cookbook](https://www.graphiti.dev/cookbooks/without-activerecord) ``` -------------------------------- ### Define Polymorphic Models in Ruby Source: https://github.com/graphiti-api/graphiti-api.github.io/blob/master/guides/concepts/resources.md Illustrates the setup for polymorphic resources in Ruby on Rails, showing example ActiveRecord models (`Employee`, `Task`, `Bug`, `Feature`) where a single query can return different types of resources. This is akin to Single Table Inheritance (STI). ```ruby class Employee < ApplicationRecord has_many :tasks end # tasks table has a 'type' column class Task < ApplicationRecord belongs_to :employee end class Bug < Task end # ONLY Feature has #points class Feature < Task def points 5 end end ```