One place for hosting & domains

      How To Add and Style a Profile Image To Your Webpage With HTML



      Part of the Series:
      How To Build a Website With HTML

      This tutorial series will guide you through creating and further customizing this website using HTML, the standard markup language used to display documents in a web browser. No prior coding experience is necessary but we recommend you start at the beginning of the series if you wish to recreate the demonstration website.

      At the end of this series, you should have a website ready to deploy to the cloud and a basic familiarity with HTML. Knowing how to write HTML will provide a strong foundation for learning additional front-end web development skills, such as CSS and JavaScript.

      In this tutorial, we’ll walk through the steps of adding and styling the top profile image as displayed in the demonstration site.

      Top section of demonstration website

      Before we get started, you may want to pick a personal profile photo for including on your site. If you don’t have a profile photo, you can use any image for demonstration purposes or create an avatar through a site like Getavataaars.com. Otherwise, you can use the image from our demonstration site by downloading the image here. (For a refresher on how to add images to webpages using HTML, please visit our tutorial HTML Images from earlier in this tutorial series.)

      Once you’ve selected an image, save it as small-profile.jpg in your image folder.

      Paste the following <img> element in between the opening and closing <div> tags you created in the last tutorial like so:

      ...
      <div style="background-image: url('ImageLocation');
        background-size: cover; height:540px;">
      <img src="https://www.digitalocean.com/community/tutorials/ImageFilePath" style="height:150px;">
      </div>
      ...
      

      Make sure to switch out the highlighted src address with the file path of your profile image. Note that we are also using the style attribute to specify the height of the image to 150 pixels. The <img> element does not require a closing tag.

      Save and reload the page in the browser to check your results. You should receive the following:

      Profile image on background image

      Next, let’s add properties to our style attribute that will give our image a circular shape, a yellow border, and a top margin that push our image 80 pixels down from the top of the page.

      Add the highlighted properties to your <img> element:

      <img src="https://www.digitalocean.com/community/tutorials/ImageFilePath" style="height:150px; border-radius: 50%; border: 10px solid #FEDE00; margin-top:80px;">
      

      Make sure you still have the correct file path of your image listed as the src address. Save the file and reload it in the browser. You should receive something like this:

      Styled profile image

      Before moving on, let’s briefly pause to study the code modifications we just made. Setting the border-radius value to 50% gives the image a circular shape. Setting the border value to 10px solid #FEDE00 gives the image a solid border that is 10 pixels wide and has the hexadecimal color value #FEDE00. The margin-top property sets the top margin to 80 pixels.

      You should now know how to add and style a profile image to your website with HTML. We are now ready to add a title and subtitle to the webpage in the next tutorial.



      Source link

      How To Set Up a Ruby on Rails GraphQL API


      The author selected Free Press to receive a donation as part of the Write for DOnations program.

      Introduction

      GraphQL is a strongly typed query language for APIs and a server-side runtime for executing those queries with your existing data. GraphQL allows clients to fetch multiple resources from the server in a single request by giving clients the ability to specify the exact data needed in the query. This removes the need for multiple API calls. GraphQL is language and database independent, and thus can be implemented in almost every programming language alongside any database of choice.

      In this tutorial, you will build a GraphQL-powered Ruby on Rails API for taking notes. When you are finished, you will be able to create and view notes from the API using GraphQL.

      GraphiQL IDE

      If you would like to take a look at the code for this tutorial, check out the companion repository for this tutorial on the DigitalOcean Community GitHub.

      Prerequisites

      To follow this tutorial, you’ll need:

      • The Ruby programming language and the Ruby on Rails framework installed on your development machine. This tutorial was tested on version 2.6.3 of Ruby and version 6.0.2.1 of Rails, so make sure to specify these versions during the installation process. Follow one of these tutorials to install Ruby and Rails:
      • PostgreSQL installed. To follow this tutorial, use PostgreSQL version 11.2. Install PostgreSQL by following Steps 1 and 2 of one of the following tutorials:

      Step 1 — Setting Up a New Rails API Application

      In this step, you will set up a new Rails API application and connect it to a PostgreSQL database. This will serve as the foundation for the note-taking API.

      Rails provides commands that make building modern web applications faster for developers. These commands can perform actions that range from creating a new Rails application to generating files required for app development. For a full list of these commands and what they do, run the following command in your terminal window:

      This command yields an extensive list of options you can use to set the parameters of your application. One of the commands listed is the new command, which accepts an APP_PATH and creates a new Rails application at the specified path.

      Create a new Rails application using the new generator. Run the following command in your terminal window:

      • rails new rails_graphql -d=postgresql -T --api

      This creates a new Rails application in a directory named rails_graphql and installs the required dependencies. Let’s go over the flags associated with the new command:

      • The -d flag pre-configures the application with the specified database.
      • The -T flag instructs Rails to not generate test files since you won’t be writing tests in this tutorial. You can also use this flag if you plan to use a different testing framework other than the one provided by Rails.
      • The --api flag configures a Rails application with only the files required for building an API with Rails. It skips configuring settings needed for browser applications.

      Once the command is done running, switch to the newly created rails_graphql directory, which is the application’s root directory:

      Now that you have successfully set up a new Rails API application, you have to connect it to a database before you can run the app. Rails provides a database.yml file found in config/database.yml, which contains configurations for connecting your app to a different database for different development environments. Rails specifies a database name for different development environments by appending an underscore (_) followed by the environment name to your app’s name. You can always change any environment database name to whatever you choose.

      Note: You can alter config/database.yml to choose the PostgreSQL role you would like Rails to use to create your database. If you created a role that is secured by a password, follow the instructions in Step 4 of How To Use PostgreSQL with Your Ruby on Rails Application on Ubuntu 18.04 or How To Use PostgreSQL with Your Ruby on Rails Application on macOS to configure your role.

      Rails includes commands for creating and working with databases. With your database credentials in place, run the following command in your terminal window to create your databases:

      The db:create command creates a development and test database based on the information provided in the config/database.yml file. Running the command yields the following output:

      Output

      Created database 'rails_graphql_development' Created database 'rails_graphql_test'

      With your application now successfully connected to a database, you can test the application to ensure it works. Start your server with the following command if you are working locally:

      If you are working on a development server, you can start your application by specifying the IP address the server should bind to:

      • bundle exec rails server --binding=your_server_ip

      Note: The server listens on port 3000. If you’re working on a development server, ensure that you have opened port 3000 in your firewall to allow connections.

      The rails server command launches Puma, a web server for Ruby distributed with Rails. The --binding=your_server_ip command binds the server to any IP you provide.

      Once you run this command, your command prompt will be replaced with the following output:

      Output

      => Booting Puma => Rails 6.0.2.1 application starting in development => Run `rails server --help` for more startup options Puma starting in single mode... * Version 4.3.1 (ruby 2.6.3-p62), codename: Mysterious Traveller * Min threads: 5, max threads: 5 * Environment: development * Listening on tcp://127.0.0.1:3000 * Listening on tcp://[::1]:3000 Use Ctrl-C to stop

      To run your application, navigate to localhost:3000 or http://your_server_ip:3000 in your browser. You’ll see the Rails default welcome page:

      Rails welcome page

      The welcome page means you have properly set up your Rails application.

      To stop the server, press CTRL+C in the terminal window where the server is running.

      You have successfully set up a Rails API application for a note-taking API. In the next step, you will set up your Rails API application to receive and execute GraphQL queries.

      Step 2 — Setting Up GraphQL for Rails

      In this step, you will configure your Rails API application to work with GraphQL. You will install and set up the necessary gems required for GraphQL development in Rails.

      As previously mentioned, GraphQL is language agnostic and is implemented in many programming languages. The graphql-ruby gem is the Ruby implementation for GraphQL. GraphQL also provides an interactive in-browser IDE known as GraphiQL for running GraphQL queries. The graphiql-rails gem helps you add GraphiQL to your development environment.

      To install these dependencies, open the project’s Gemfile for editing, using nano or your favorite text editor:

      Add the graphql and graphiql-rails gems to your Gemfile. You can add the graphiql gem anywhere, but the graphiql-rails gem should be added under the development dependencies:

      ~/rails_graphql/Gemfile

      ...
      group :development do
        gem 'listen', '>= 3.0.5', '< 3.2'
        # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
        gem 'spring'
        gem 'spring-watcher-listen', '~> 2.0.0'
        gem 'graphiql-rails'
      end
      
      gem 'graphql', '1.9.18'
      ...
      

      Save and close the file when you are done adding the gems.

      In your terminal window, use the following command to install the gems:

      The output shows that the gems are installed.

      The graphql gem provides generators to create various files. To view the available generators, run the following command in your terminal window:

      The generators prefixed with graphql: are the ones associated with the graphql gem.

      You will use the graphql:install command to add graphql-ruby boilerplate code to the application and mount GraphiQL in your development environment. The boilerplate code will include all the files and directory needed for the graphql-ruby gem to work with Rails.

      In your terminal window, run the following commands:

      This command generates several files, including a graphql_controller.rb file located at app/controllers/graphql_controller.rb and a graphql directory at app/graphql which contains files required to get started with GraphQL in Rails. It also adds a /graphql HTTP POST route in the routes file located at config/routes.rb. This route is mapped to the app/controllers/graphql_controller.rb#execute method which handles all queries to the GraphQL server.

      Before you can test the GraphQL endpoint, you need to mount the GraphiQL engine to the routes file so you can access the GraphiQL in-browser IDE. To do this open the routes file located at config/routes.rb:

      • nano ~/rails_graphql/config/routes.rb

      Add the following code to the file to mount the GraphiQL engine in the development environment:

      ~/rails_graphql/config/routes.rb

      Rails.application.routes.draw do
        if Rails.env.development?
          mount GraphiQL::Rails::Engine, at: "/graphiql", graphql_path: "graphql#execute"
        end
        post "/graphql", to: "graphql#execute"
        # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
      end
      

      This mounts the GraphiQL engine to the /graphiql path and directs all queries to the graphql#execute method.

      Since this is an API application created with the --api flag, it does not expect to render any page in the browser. To make the GraphiQL editor show up in the browser, you need to make a couple of small changes to your application’s configuration.

      First, open the application.rb file located at config/application.rb:

      • nano ~/rails_graphql/config/application.rb

      Next, uncomment the require "sprockets/railtie" line:

      ~/rails_graphql/config/application.rb

      require_relative 'boot'
      
      require "rails"
      # Pick the frameworks you want:
      require "active_model/railtie"
      require "active_job/railtie"
      require "active_record/railtie"
      require "active_storage/engine"
      require "action_controller/railtie"
      require "action_mailer/railtie"
      require "action_mailbox/engine"
      require "action_text/engine"
      require "action_view/railtie"
      require "action_cable/engine"
      require "sprockets/railtie"
      # require "rails/test_unit/railtie"
      
      ...
      

      Save and close the file after uncommenting the line.

      Now create a config directory at app/assets:

      • mkdir -p app/assets/config

      Next, create a manifest.js file in the newly created config directory. The manifest.js file specifies additional assets to be compiled and made available to the browser:

      • nano app/assets/config/manifest.js

      Add the following code to the file which tells Rails to precompile the graphiql/rails/application.css and graphiql/rails/application.js files so Rails can serve them to your browser:

      ~/rails_graphql/app/assets/config/manifest.js

      //= link graphiql/rails/application.css
      //= link graphiql/rails/application.js
      

      Save and close the file.

      With that done, you can test your GraphQL endpoint. Restart your development server, and in your browser, navigate to localhost:3000/graphiql or http://your_server_ip:3000/graphiql. The GraphiQL query editor displays in your browser:

      GraphiQL IDE

      The left side of the GraphiQL IDE accepts GraphQL queries and the right side displays results of the run query. The GraphiQL query editor also has a syntax highlighter and a typeahead hinter powered by your GraphQL Schema. Together, these help you make a valid query.

      To try a Hello World example, clear out the default text in the editor’s left pane and type in the following query:

      query {
          testField
      }
      

      Click the Play icon button in the header and you’ll recieve a successful response on the screen, as shown in the following figure:

      GraphiQL IDE Response successful response

      You have successfully set up your Rails API application to work with GraphQL and tested your GraphQL endpoint to confirm it works. In the next step, you will create GraphQL types for your application.

      Step 3 — Creating Types for the Application

      GraphQL depends on its Types and Schema to validate and respond to queries. In this step, you will create a Note model and the GraphQL types required in your note-taking API.

      A GraphQL type consists of fields and arguments which, in turn, define the fields and arguments that can appear in any GraphQL query that operates on that type. These types make up a GraphQL Schema. GraphQL defines the following types:

      • The Query and Mutation types: These are special types that define the entry point of every GraphQL query. Every GraphQL service has a query type and may or may not have a mutation type.
      • Object types: These are the basic components of a GraphQL schema. These represent the objects you can fetch from a GraphQL service and the fields each object holds.
      • Scalar types: These are default types that come with GraphQL out of the box. They include Int, Float, String, Boolean, and ID.
      • Enumeration types: These are types that define a particular set of allowed values.
      • Input types: These are similar to object types, with the only difference being that they define objects that you can pass to queries as arguments.

      There are other types, including Union, List, Non-Null, and Interface. You can find a list of available GraphQL types in the official GraphQL documentation.

      For this application, you will create a Note model and a Note object and input type. The Note model will represent the database table that will store your notes while the Note object and input type will define the fields and arguments that exists on a Note object.

      First, create a Note model using the generate model subcommand provided by Rails and specify the name of the model along with its columns and data types. Run the following command in your terminal window:

      • rails generate model note title:string:index body:text

      This command creates a Note model with two fields: title, with the type string, and body, with the type text. The command also adds a database index on the title column. It generates these two files:

      • A note.rb file located at app/models/note.rb. This file will hold all model-related logic.
      • A 20200617173228_create_notes.rb file (the number at the beginning of the file will differ, depending on the date you run the command) located at db/migrate/20200617173228_create_notes.rb. This is a migration file that holds the instruction for creating a corresponding notes table in the database.

      To execute the instructions in the migration file, you’ll use the db:migrate subcommand which executes the instruction in your migration files. Run the following command in your terminal window:

      Once the command runs successfully, you will see output similar to the following:

      Output

      == 20200617173228 CreateNotes: migrating ====================================== -- create_table(:notes) -> 0.0134s -- add_index(:notes, :title) -> 0.0073s == 20200617173228 CreateNotes: migrated (0.0208s) =============================

      With the note model in place, next you’ll create a NoteType. A valid note object is expected to have an id, a title, and text. Run the following command in your terminal window to create a NoteType:

      • rails generate graphql:object Note id:ID! title:String! body:String!

      The command instructs Rails to create a GraphQL object type called Note with three fields: an id field with a type of ID, and the title and body fields, each with a String type. The exclamation point (!) appended to the field type indicates that the field should be non-nullable, meaning that the field should never return a null value. Non-nullable fields are important, as they serve as a form of validation that guarantees which fields must be present whenever GraphQL objects are queried.

      Running the preceding command creates a note_type.rb file located at app/graphql/types/note_type.rb containing a Types::NoteType class with three non-nullable fields.

      Lastly, you will create a NoteInput type to define the arguments required to create a note. Start by creating an input directory under app/graphql/types. The input directory will house input types:

      • mkdir ~/rails_graphql/app/graphql/types/input

      Note: It’s not a requirement to create input types in the input directory; it is merely a common convention. You can decide to keep all your types under the types directory and exclude nesting the class under an Input module whenever you’re accessing it.

      In the ~/rails_graphql/app/graphql/types/input directory, create a note_input_type.rb file:

      • nano ~/rails_graphql/app/graphql/types/input/note_input_type.rb

      Add the following code to the file to define the fields for the Input type:

      ~/rails_graphql/app/graphql/types/input/note_input_type.rb

      module Types
        module Input
          class NoteInputType < Types::BaseInputObject
            argument :title, String, required: true
            argument :body, String, required: true
          end
        end
      end
      

      In the note_input_type.rb file, you added a Types::Input::NoteInputType class that inherits from the Types::BaseInputObject class and accepts two required arguments; title and body, both of a string type.

      You’ve created a model and two GraphQL types for your note-taking app. In the next step, you will create queries to fetch existing notes.

      Step 4 — Creating Queries for the Application

      Your GraphQL-powered API is gradually coming together. In this step you’ll create two queries; one to fetch a single note by id and another to fetch all notes. The GraphQL query type handles the fetching of data and can be likened to a GET request in REST.

      First, you’ll create a query to fetch all notes. To start, create a queries directory to house all queries:

      • mkdir ~/rails_graphql/app/graphql/queries

      In the app/graphql/queries directory, create a base_query.rb file from which all other query classes will inherit:

      • nano ~/rails_graphql/app/graphql/queries/base_query.rb

      Add the following code to the base_query.rb file to create a BaseQuery class that other query classes will inherit from:

      ~/rails_graphql/app/graphql/queries/base_query.rb

      module Queries
        class BaseQuery < GraphQL::Schema::Resolver
        end
      end
      

      In the base_query.rb file, you added a Queries::BaseQuery class that inherits from the GraphQL::Schema::Resolver class. The GraphQL::Schema::Resolver class is a container that can hold logic belonging to a field. It can be attached to a field with the resolver: keyword.

      The Queries::BaseQuery class can also contain any code you intend to reuse across multiple query classes.

      Next, create a fetch_notes.rb file in the queries directory. This file will hold the logic for fetching all existing notes, and will be attached to a field in the query type file:

      • nano ~/rails_graphql/app/graphql/queries/fetch_notes.rb

      Add the following code to the file to define the return object type and resolve the requested notes:

      ~/rails_graphql/app/graphql/queries/fetch_notes.rb

      module Queries
        class FetchNotes < Queries::BaseQuery
      
          type [Types::NoteType], null: false
      
          def resolve
            Note.all.order(created_at: :desc)
          end
        end
      end
      

      In the fetch_notes.rb file, you created a Queries::FetchNotes class that inherits the Queries::BaseQuery previously created. The class has a return type declaration that declares that the data returned by this query should be an array of the already created NoteType.

      The Queries::FetchNotes also contains a resolve method that returns an array of all existing notes sorted by their created date in descending order.

      The FetchNotes query is ready to receive and return requests for notes, but GraphQL is still unaware of its existence, to fix that, open the GraphQL query type file located at app/graphql/types/query_type.rb:

      • nano ~/rails_graphql/app/graphql/types/query_type.rb

      The query_type.rb file is the entry point for all GraphQL query types. It holds the query fields, and their respective resolver methods. Replace the sample code in the file with the following:

      ~/rails_graphql/app/graphql/types/query_type.rb

      module Types
        class QueryType < Types::BaseObject
          # Add root-level fields here.
          # They will be entry points for queries on your schema.
      
          field :fetch_notes, resolver: Queries::FetchNotes
        end
      end
      

      In the query_type.rb file, you added a fetch_notes field and attached it to the Queries::FetchNotes class using a resolver:. This way whenever the fetch_notes query is called, it executes the logic in the resolve method of the Queries::FetchNotes class.

      In order to test your query, you need some data to fetch, but you currently don’t have any notes in your database. You can fix that by adding some seed data to your database. Open the seeds.rb file located at db/seeds.rb:

      • nano ~/rails_graphql/db/seeds.rb

      Add the following code to the file to create five notes:

      ~/rails_graphql/db/seeds.rb

      5.times do |i|
        Note.create(title: "Note #{i + 1}", body: 'Lorem ipsum saves lives')
      end
      

      Save and close the file after adding the code.

      Open your project’s root directory in another terminal window and run the following command to run the code in the seed.rb file:

      This creates 5 notes in the database.

      With data in your database, and your development server running, navigate to localhost:3000/graphiql or http://your_server_ip:3000/graphiql in your browser to open your GraphiQL IDE. In the left side of the editor, type in the following query:

      query {
        fetchNotes {
          id
          title
          body
        }
      }
      

      This GraphQL query declares a query operation, indicating you want to make a query request. In the query operation, you called a fetchNotes field that matches the fetch_notes query field declared in the API, and included the fields on a note that you want to be returned in your response.

      Click the Play icon button in the header. You’ll see a response similar to the following in the output pane:

      {
        "data": {
          "fetchNotes": [
            {
              "id": "5",
              "title": "Note 5",
              "body": "Lorem ipsum saves lives"
            },
            {
              "id": "4",
              "title": "Note 4",
              "body": "Lorem ipsum saves lives"
            },
            {
              "id": "3",
              "title": "Note 3",
              "body": "Lorem ipsum saves lives"
            },
            {
              "id": "2",
              "title": "Note 2",
              "body": "Lorem ipsum saves lives"
            },
            {
              "id": "1",
              "title": "Note 1",
              "body": "Lorem ipsum saves lives"
            }
          ]
        }
      }
      

      The response contains an array of 5 notes that match the fields declared in the query on the left. If you remove some fields in the query on the left side of the editor and re-run the query, you get a response with only the fields you requested. That’s the power of GraphQL.

      Next, you’ll create another query to fetch notes by id. This query will be similar to the fetch_notes query, only that it’ll accept an id argument. Go ahead and create a fetch_note.rb file in the queries directory:

      • nano ~/rails_graphql/app/graphql/queries/fetch_note.rb

      Add the following code to the file to find and return a note with the provided id:

      ~/rails_graphql/app/graphql/queries/fetch_note.rb

      module Queries
        class FetchNote < Queries::BaseQuery
          type Types::NoteType, null: false
          argument :id, ID, required: true
      
          def resolve(id:)
            Note.find(id)
          rescue ActiveRecord::RecordNotFound => _e
            GraphQL::ExecutionError.new('Note does not exist.')
          rescue ActiveRecord::RecordInvalid => e
            GraphQL::ExecutionError.new("Invalid attributes for #{e.record.class}:"
              " #{e.record.errors.full_messages.join(', ')}")
          end
        end
      end
      

      This defines a Queries::FetchNote class that inherits from the Queries::BaseQuery class. This class not only returns a single item that must be of a NoteType, it also accepts an id argument with an ID type. The resolve method receives the provided id argument, then finds and returns a note with the provided id. If no note exists or an error occurs, it is rescued and returned as a GraphQL::ExecutionError.

      Next, you will attach the Queries::FetchNote class to a query field in the query type file. Open the query_type.rb file in your editor:

      • nano ~/rails_graphql/app/graphql/types/query_type.rb

      Add the following code to the file which defines a resolver for fetch_notes:

      ~/rails_graphql/app/graphql/types/query_type.rb

      module Types
        class QueryType < Types::BaseObject
          # Add root-level fields here.
          # They will be entry points for queries on your schema.
      
          field :fetch_notes, resolver: Queries::FetchNotes
          field :fetch_note, resolver: Queries::FetchNote
        end
      end
      

      To test your new query, ensure your server is running and navigate to localhost:3000/graphiql or http://your_server_ip:3000/graphiql in your browser to open your GraphiQL IDE. In the left side of the editor, type in the following query:

      query {
        fetchNote(id: 1) {
          id
          title
          body
        }
      }
      

      This query operation requests a fetchNote field, which corresponds to the fetch_note query field, and is passed an id argument. It specifies that we want three fields to be returned in the response.

      Run the query by clicking the Play icon button in the header. You will get a response like the following in the output pane:

      {
        "data": {
          "fetchNote": {
            "id": "1",
            "title": "Note 1",
            "body": "Lorem ipsum saves lives"
          }
        }
      }
      

      The response contains a single note that matches the requested id with fields matching the ones in the request.

      In this step, you created GraphQL queries to fetch notes from your API. Next you’ll write mutations to create notes.

      Step 5 — Creating GraphQL Mutations to Modify Notes

      In addition to queries, GraphQL also defines a mutation type for operations that modify server-side data. Just as REST provides POST, PUT, PATCH, and DELETE requests for creating, updating and deleting resources, GraphQL’s mutation type defines a convention for operations that cause writes on the server-side. In this step, you’ll create a mutation for adding new notes.

      graphQL-ruby includes two classes for writing mutations. They are:

      • GraphQL::Schema::Mutation: This is the generic base class for writing mutations. If you don’t want an input argument required in your mutations, you should use this class.
      • GraphQL::Schema::RelayClassicMutation: This is a base class with some conventions; an argument called clientMutationId that is always inserted to the response, and mutations that accepts one argument called input. This class is used by default when you use the install generator to add boilerplate GraphQL files to your project.

      Create an add_note.rb file in the mutations directory located at app/graphql/mutations:

      • nano ~/rails_graphql/app/graphql/mutations/add_note.rb

      Add the following code to the file to define the mutation for adding new notes:

      ~/rails_graphql/app/graphql/mutations/add_note.rb

      module Mutations
        class AddNote < Mutations::BaseMutation
          argument :params, Types::Input::NoteInputType, required: true
      
          field :note, Types::NoteType, null: false
      
          def resolve(params:)
            note_params = Hash params
      
            begin
              note = Note.create!(note_params)
      
              { note: note }
            rescue ActiveRecord::RecordInvalid => e
              GraphQL::ExecutionError.new("Invalid attributes for #{e.record.class}:"
                " #{e.record.errors.full_messages.join(', ')}")
            end
          end
        end
      end
      

      This defines a Mutations::AddNote class that inherits from the Mutations::BaseMutation class, which is one of the classes created when you ran the install generator while installing the GraphQL-Ruby gem. The Mutations::AddNote class receives an argument with the name params and a type of NoteInputType, which you created in Step 3. It also returns a field called note that must be a non-null NoteType type.

      The resolve method of the class receives the params and converts it to a hash which it uses to create and return a new hash containing the new note. If there’s an error while creating the note, the error is rescued and returned as a GraphQL::ExecutionError.

      Note: The resolve method in a mutation must return a hash whose symbol matches the field names.

      Like with queries, the Mutations::AddNote mutation has to be attached to a mutation field using the mutation: keyword.

      Open the mutation type file located at app/graphql/types/mutation_type.rb in your editor:

      • nano ~/rails_graphql/app/graphql/types/mutation_type.rb

      Replace the code in the file with the following code, which adds a field for the add_note with its corresponding mutation class:

      ~/rails_graphql/app/graphql/types/mutation_type.rb

      module Types
        class MutationType < Types::BaseObject
          field :add_note, mutation: Mutations::AddNote
        end
      end
      

      In this code, you added an add_note field to the mutation type file and attached it to the Mutations::AddNote class using the mutation: keyword. When the add_note mutation is called, it runs the code in the resolve method of the Mutations::AddNote class.

      To test your new mutation, navigate to localhost:3000/graphiql or http://your_server_ip:3000/graphiql in your browser to open your GraphiQL IDE. In the left side of the editor, type in the following query:

      mutation {
        addNote(input: { params: { title: "GraphQL notes", body: "A long body of text about GraphQL"  }}) {
          note {
            id
            title
            body
          }
        }
      }
      

      This declares a mutation operation with an addNote field that accepts a single input argument, which in turn accepts a param object with keys that match the NoteInputType. The mutation operation also includes a note field that matches the note field returned by the Mutations::AddNote class.

      Run the mutation in GraphiQL and you’ll see the following results in the output pane:

      {
        "data": {
          "addNote": {
            "note": {
              "id": "6",
              "title": "GraphQL notes",
              "body": "A long body of text about GraphQL"
            }
          }
        }
      }
      

      The response returned is the newly created note with the fields requested in the mutation request.

      With your add_note mutation now working, your API can fetch and create notes using GraphQL queries and mutations.

      Conclusion

      In this tutorial, you created a note-taking API application with Ruby on Rails using PostgreSQL as your database and GraphQL as your API query language. You can learn more about GraphQL on its official website. The GraphQL-Ruby gem website also contains some guides to help you work with GraphQL in Rails.



      Source link

      Apache Network Error AH00072: make_sock: could not bind to address



      Part of the Series:
      Common Apache Errors

      This tutorial series explains how to troubleshoot and fix some of the most common errors that you may encounter when using the Apache web server.

      Each tutorial in this series includes descriptions of common Apache configuration, network, filesystem, or permission errors. The series begins with an overview of the commands and log files that you can use to troubleshoot Apache. Subsequent tutorials examine specific errors in detail.

      Introduction

      An Apache AH00072: make_sock: could not bind to address error message is generated when there is another process listening on the same port that Apache is configured to use. Typically the port will be the standard port 80 for HTTP connections, or port 443 for HTTPS connections. However, any port conflict with another process can cause an AH00072 error.

      The error is derived from the underlying operating system system’s network stack. The issue is that only a single process can be bound to a port at any given time. If another web server like Nginx is configured to listen on port 80 and it is running, then Apache will not be able to claim the port for itself.

      To detect a port conflict with Apache, you will need to examine systemctl and journalctl output to determine the IP address and port that are causing the error. Then you can decide how to resolve the issue, whether it is by switching web servers, changing the IP address that Apache uses, the port, or any combination of these options.

      Troubleshooting with systemctl

      Following the troubleshooting steps from the How to Troubleshoot Common Apache Errors tutorial at the beginning of this series, the first step when you are troubleshooting an AH00072: make_sock: could not bind to address error message is to check Apache’s status with systemctl.

      If systemctl does not include output that describes the problem, then the last section of this tutorial, Troubleshooting Using journalctl Logs explains how to examine the systemd logs to find the conflicting port.

      The output from systemctl status will in many cases contain all the diagnostic information that you need to resolve the error. It will include the IP address that Apache is using, as well as the port that it is attempting to bind to. The output will also indicate how long Apache has been unable to start so that you can determine how long the issue has been affecting Apache.

      On Ubuntu and Debian-derived Linux distributions, run the following to check Apache’s status:

      Ubuntu and Debian Systems

      • sudo systemctl status apache2.service -l --no-pager

      On CentOS and Fedora systems, use this command to examine Apache’s status:

      CentOS and Fedora Systems

      • sudo systemctl status httpd.service -l --no-pager

      The -l flag will ensure that systemctl outputs the entire contents of a line, instead of substituting in ellipses () for long lines. The --no-pager flag will output the entire log to your screen without invoking a tool like less that only shows a screen of content at a time.

      Since you are troubleshooting an AH00072: make_sock error message, you should receive output that is similar to the following:

      Output

      ● httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled) Active: failed (Result: exit-code) since Tue 2020-07-28 13:58:40 UTC; 8s ago Docs: man:httpd.service(8) Process: 69 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE) Main PID: 69 (code=exited, status=1/FAILURE) Status: "Reading configuration..." Tasks: 213 (limit: 205060) Memory: 25.9M CGroup: /system.slice/containerd.service/system.slice/httpd.service Jul 28 13:58:40 e3633cbfc65e systemd[1]: Starting The Apache HTTP Server… Jul 28 13:58:40 e3633cbfc65e httpd[69]: (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80 Jul 28 13:58:40 e3633cbfc65e httpd[69]: (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80 Jul 28 13:58:40 e3633cbfc65e httpd[69]: no listening sockets available, shutting down Jul 28 13:58:40 e3633cbfc65e httpd[69]: AH00015: Unable to open logs Jul 28 13:58:40 e3633cbfc65e systemd[1]: httpd.service: Main process exited, code=exited, status=1/FAILURE Jul 28 13:58:40 e3633cbfc65e systemd[1]: httpd.service: Failed with result 'exit-code'. Jul 28 13:58:40 e3633cbfc65e systemd[1]: Failed to start The Apache HTTP Server.

      Note that your output may be slightly different if you are using an Ubuntu or Debian-derived distribution, where the name of the Apache process is not httpd but is apache2.

      This example systemctl output includes some highlighted lines from the systemd journal that describes the AH00072 error. These lines, both of which begin with (98)Address already in use: AH00072: make_sock: could not bind to address, give you all the information about the AH00072 error that you need to troubleshoot it further, so you can skip the following journalctl steps and instead proceed to the Troubleshooting with ss and ps Utilities section at the end of this tutorial.

      If your systemctl output does not give specific information about the IP address and port or ports that are causing the AH00072 error, you will need to examine journalctl output from the systemd logs. The following section explains how to use journalctl to troubleshoot an AH00072 error.

      Troubleshooting Using journalctl Logs

      If your systemctl output does not include specifics about an AH00072 error, you should proceed with using the journalctl command to examine systemd logs for Apache.

      On Ubuntu and Debian-derived systems, run the following command:

      • sudo journalctl -u apache2.service --since today --no-pager

      On CentOS, Fedora, and RedHat-derived systems, use this command to inspect the logs:

      • sudo journalctl -u httpd.service --since today --no-pager

      The --since today flag will limit the output of the command to log entries beginning at 00:00:00 of the current day only. Using this option will help restrict the volume of log entries that you need to examine when checking for errors.

      If Apache is unable to bind to a port that is in use, search through the output for lines that are similar to the following log entries, specifically lines that contain the AH00072 error code as highlighted in this example:

      Output

      -- Logs begin at Tue 2020-07-14 20:10:37 UTC, end at Tue 2020-07-28 14:01:40 UTC. -- . . . Jul 28 14:03:01 b06f9c91975d apachectl[71]: (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80 Jul 28 14:03:01 b06f9c91975d apachectl[71]: (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80 Jul 28 14:03:01 b06f9c91975d apachectl[71]: no listening sockets available, shutting down

      This output indicates two AH00072 errors. The first of these explains that Apache cannot bind to the [::]:80 address, which is port 80 on all available IPv6 interfaces. The next line, with the address 0.0.0.0:80, indicates Apache cannot bind to port 80 on all available IPv4 interfaces. Depending on your system’s configuration, the IP addresses may be different and only show individual IPs, and may only include IPv4 or IPv6 errors.

      Even though your own system may have different conflicting interfaces and ports, the errors will be similar to the output shown here. With output from journalctl you will be able to diagnose the issue using ss in the following section of this tutorial.

      Troubleshooting with ss and ps Utilities

      To troubleshoot an AH00072 error you need to determine what other process is listening on the IP address and port that Apache is attempting to use. Most modern Linux distributions include a utility called ss which can be used to gather information about the state of a system’s network sockets.

      In the previous journalctl section, something was already bound to the IPv4 and IPv6 addresses on port 80. The following command will determine the name of the process that is already bound to an IPv4 interface on port 80. Ensure that you substitute the port from the error message if it is different from 80 in the following command:

      • sudo ss -4 -tlnp | grep 80

      The flags to the ss command alter its default output in the following ways:

      • -4 restricts ss to only display IPv4-related socket information.
      • -t restricts the output to tcp sockets only.
      • -l displays all listening sockets with the -4 and -t restrictions taken into account.
      • -n ensures that port numbers are displayed, as opposed to protocol names like ‘httporhttps`. This is important since Apache may be attempting to bind to a non-standard port and a service name can be confusing as opposed to the actual port number.
      • -p outputs information about the process that is bound to a port.

      With all of those flags, you will receive output like the following:

      Output

      LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=40,fd=6))

      The first three fields are not important when troubleshooting an AH00072 error so they can be ignored. The important fields are the fourth (0.0.0.0:80), which matches the journalctl error that you discovered earlier, along with the last users:(("nginx",pid=40,fd=6)), specifically the pid=40 portion.

      If you have an AH00072 error that is related to an IPv6 interface, repeat the ss invocation, this time using the -6 flag to restrict the interfaces to the IPv6 network stack like this:

      • sudo ss -6 -tlnp |grep 80

      Output

      LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=40,fd=7))

      Again, substitute the port number in question from your journalctl output if it is different from the highlighted 80 given here.

      In both these cases of IPv4 and IPv6 errors, the ss output indicates that there is a program with process ID 40 (the pid=40 in the output) that is bound to the 0.0.0.0:80 and [::]:80 interfaces respectively. This process is preventing Apache from starting since it already owns the port. To determine the name of the program, use the ps utility like this, substituting the process ID from your output in place of the highlighted 40 value in this example:

      You will receive output that is similar to the following:

      Output

      PID TTY TIME CMD 40 ? 00:00:00 nginx

      The highlighted nginx in the output is the name of the process that is listening on the interfaces. Now that you have the name of the program that is preventing Apache from starting, you can decide how to resolve the error. You could stop the nginx process, reconfigure nginx to listen on a different interface and port, or reconfigure Apache to avoid the port collision.

      It is important to note that the process may be different from nginx and the port and IP addresses may not always be 0.0.0.0 or [::] if you are diagnosing an AH00072 error. Oftentimes, different web servers and proxies will be in use on the same server. Each may be attempting to bind to different IPv4 ports and IPv6 interfaces to handle different web traffic. For example, a server that is configured with HAProxy listening on the IPv4 loopback address (also referred to as localhost) on port 8080 will show ss output like this:

      Output

      LISTEN 0 2000 127.0.0.1:8080 0.0.0.0:* users:(("haproxy",pid=545,fd=7))

      It is important to combine systemctl output, or journalctl output that indicates specific IP addresses and ports, with diagnostic data from ss, and then ps to narrow down the process that is causing Apache to fail to start.

      Conclusion

      In this tutorial you learned how to troubleshoot an Apache AH00072 make_sock: could not bind to address error message on both IPv4 and IPv6 interfaces. You learned how to use systemctl to examine the status of the Apache server and try to find error messages. You also learned how to use journalctl to examine the systemd logs for specific information about an AH00072 error.

      With the appropriate error messages from the logs, you then learned about the ss utility and how to use it to examine the state of a system’s network sockets. After that you learned how to combine process ID information from ss with the ps utility to find the name of the process that is causing Apache to be unable to start.



      Source link