投稿時間:2023-08-27 02:05:18 RSSフィード2023-08-27 02:00 分まとめ(6件)
カテゴリー等 | サイト名等 | 記事タイトル・トレンドワード等 | リンクURL | 頻出ワード・要約等/検索ボリューム | 登録日 |
---|---|---|---|---|---|
海外TECH | DEV Community | Node.js and GraphQL Tutorial: How to build a GraphQL API with an Apollo server | https://dev.to/realsteveig/nodejs-and-graphql-tutorial-how-to-build-a-graphql-api-with-an-apollo-server-2733 | Node js and GraphQL Tutorial How to build a GraphQL API with an Apollo serverINTRODUCTIONWelcome to my tutorial on building a GraphQL API with an Apollo Server using Node js In this guide I will show you how to harness the power of GraphQL to create efficient and flexible APIs for your applications So what exactly is GraphQL Imagine a world where you can request exactly the data you need from your server no more and no less GraphQL is a query language that allows you to do just that Unlike traditional REST APIs where you often receive a fixed set of data in predefined endpoints GraphQL empowers you to shape your queries to match your specific requirements It s like having a tailor made API at your fingertips Comparing GraphQL to REST is like comparing a custom made suit to off the rack clothing With REST you might end up over fetching or under fetching data causing inefficiencies But with GraphQL you have the freedom to ask for only the fields you need eliminating unnecessary data transfer and optimizing your app s performance But that s not all GraphQL also excels in its ability to consolidate multiple data sources into a single query No more juggling between different endpoints to assemble the data you need GraphQL brings it all together in one elegant request Whether you re building a simple to do app or a complex e commerce platform GraphQL s flexibility and efficiency can revolutionize the way you interact with APIs Throughout this tutorial I ll guide you step by step in creating a GraphQL API using an Apollo Server with Node js You ll learn how to define your data schema and fetch data from MongoDB using resolvers for a seamless experience So if you re ready to dive into the world of GraphQL and unlock its potential let s get started FOLDER STRUCTUREWhen diving into building a GraphQL API with an Apollo Server having a clear and organized folder structure is key Here s a suggested layout for your project s folder structure drawing parallels to how things might be organized in a traditional RESTful API project project root src schema GraphQL schema definitions resolvers Resolver functions for handling queries and mutations models Data models or database schemas app js GraphQL server setup package json Project dependencies and scripts gitignore Git ignore configurations env Environment variables optional Here s what each folder represents schema Think of the schema folder as similar to the routes or endpoints in a RESTful API Here you define your GraphQL schema using a Schema Definition Language SDL This schema outlines the types queries mutations and even subscriptions that your API will support It s the heart of your API s structure resolvers Just as controllers handle the logic for different routes in a RESTful API resolvers in the resolvers folder handle the logic for various fields in your GraphQL schema Each resolver function corresponds to a specific field and contains the actual code that fetches data interacts with databases and performs the required operations Resolvers are where the magic happens similar to how controllers execute the actions in a RESTful API models The models folder houses your data models which are equivalent to the database schema in a RESTful API context These models define the structure and relationships of your data In resolvers you utilize these models to interact with your data sources just as you would in a RESTful API s database layer app js The app js file takes on the role of setting up and configuring your GraphQL server This is equivalent to the server configuration and middleware setup you might do in the main file of a RESTful API package json This file remains the same regardless of whether you re working with REST or GraphQL It lists your project s dependencies and scripts for managing your API much like in a RESTful API project gitignore Similar to a RESTful API project the gitignore file helps you specify files and directories that should be ignored by version control Git env Optionally you can use the env file to store environment variables for your application just like in a RESTful API Remember while this suggested folder structure draws parallels to RESTful design it s adaptable to your project s specific needs and your development preferences It provides a roadmap for organizing your GraphQL API project effectively leveraging concepts you might already be familiar with from working with RESTful APIs PACKAGESFor this project you will need to install the following packages mongoose bcryptjs dotenv apollo server graphql tools mergeLet s briefly talk about these packages mongoose ODM library for MongoDB and Node js aiding data modeling and interaction bcryptjs Library for secure password hashing and comparison dotenv Loads environment variables from env files ensuring secure configuration apollo server GraphQL server implementation for streamlined schema execution and validation graphql tools merge Utility for combining multiple GraphQL schemas into one cohesive schema Because I am using typescript my folder structure and package json file now look like this Now update the src db connect ts file with the code below to establish a connection to your Mongo database import mongoose from mongoose export const connectDB url string gt return mongoose connect url then gt console log Connected to database catch err gt console log err For this project I created two models User and Products This is what they look like src model user tsimport Schema Model model Document from mongoose import bcrypt from bcryptjs export interface IUser extends Document username string email string password string isValidPassword password string gt Promise lt boolean gt const UserSchema Schema new Schema username type String required true unique true email type String required true password type String required true UserSchema pre save async function const salt await bcrypt genSalt this password await bcrypt hash this password salt UserSchema methods isValidPassword async function password string const compare await bcrypt compare password this password return compare export const User Model lt IUser gt model lt IUser gt User UserSchema src model product tsimport Schema Model model Document from mongoose export interface IProduct extends Document name string price number const ProductSchema Schema new Schema name type String required true price type Number required true export const Product Model lt IProduct gt model lt IProduct gt Product ProductSchema Now that we have successfully created a database schema for our API let us head straight to create the schema for our GraphQL queries and Mutations For the users schema update src schema user ts to look like this import buildSchema from graphql export const usersGQLSchema buildSchema type User id String username String email String password String type Query users usersInfoResponse user id String User type usersInfoResponse success Boolean total Int users User type Mutation regUser username String email String password String User loginUser email String password String User updateUser id String username String email String password String User deleteUser id String deleteResponse type deleteResponse success Boolean message String id String Let me break down everything this code presents Types Like Data StructuresType User Just as in RESTful APIs a type in GraphQL defines what data looks like For instance User is like a blueprint for a user s data including properties such as ID username email and password Queries Retrieving DataQuery users Think of this as a way to request a list of users Similar to a RESTful API endpoint you re asking for user information The exclamation point after usersInfoResponse indicates that this query always returns a response with users information Query user id This is like getting details about one user just as you would in a RESTful API by providing an ID The id parameter is marked with an exclamation point to show that it s required for the query to work The exclamation point after User indicates that this query always returns user information Mutations Modifying DataMutation regUser loginUser Similar to creating a new resource in REST this mutation lets you signup signin a new user The exclamation points after username email and password indicate that these fields are required for creating a user The exclamation point after User indicates that the mutation always returns the newly created user s information Mutation updateUser id This is like updating a user s information comparable to editing a resource in REST The id is required and you can modify username email or password If you don t provide an exclamation point it means the field is optional Mutation deleteUser id Just as you might delete a resource in REST this mutation removes a user The id is required and the exclamation point after deleteResponse indicates that it always returns a response Custom Response Types Structured ResponsesType usersInfoResponse This is like the response you might get when requesting a list of users in REST The exclamation point after success total and users means that these fields are always included in the response Type deleteResponse Comparable to a response when deleting a resource in REST this type always includes success message and id In essence GraphQL s exclamation points highlight required fields just like in RESTful APIs They ensure that when you make a query or mutation you get back the data you need with certainty After creating our User schema let us create the resolver or controllers to implement the logic Update src resolver user ts with this code import User from model user interface Args id string username string email string password string export const UsersResolver Query users async gt try const users await User find if users throw new Error No users found return success true total users length users catch error throw error user async any args Args gt try if args id throw new Error No id provided const user await User findById args id if user throw new Error No user found return user catch error throw error Mutation regUser async any args Args gt try const user await User findOne email args email if user throw new Error User already exists const newUser await User create username args username email args email password args password return newUser catch error throw error loginUser async any args Args gt try const user await User findOne email args email if user throw new Error User not found const isValid await user isValidPassword args password if isValid throw new Error Invalid password return user catch error throw error updateUser async any args Args gt try const id args id if id throw new Error No id provided const user await User findById args id if user throw new Error User not found const updateUser await User findByIdAndUpdate id args new true runValidators true return updateUser catch error throw error deleteUser async any args Args gt try const id args id if id throw new Error No id provided const user await User findById args id if user throw new Error User not found const deleteUser await User findByIdAndDelete id return success true message User deleted successfully id deleteUser id catch error throw error In the code above The UsersResolver object is created containing resolvers for both queries and mutations The Query section contains two resolvers users Fetches all users from the database and returns a response containing information about users user Fetches a user by their provided ID from the database The Mutation section contains several resolvers for various operations each performing a specific action regUser Registers a new user if they don t already exist in the database loginUser Validates user credentials and returns the user if login is successful updateUser Updates a user s information based on their ID deleteUser Deletes a user by their ID Each resolver uses asynchronous code async await to interact with the database and handle potential errors The Args interface defines the expected arguments for the resolver functions For instance each mutation requires id username email and password parameters This code demonstrates how GraphQL resolvers work to fetch create update and delete data while interacting with a User model from an external module It s similar to the logic you might use in controllers for RESTful APIs where each resolver corresponds to a specific API operation Great work now that we have successfully implemented the logic for Users let us repeat the same process by creating a schema and a resolver for Products src schema products tsimport buildSchema from graphql export const productsGQLSchema buildSchema type Product id String name String price Int type Query products productsInfoResponse product id String Product type productsInfoResponse success Boolean total Int products Product type Mutation addProduct name String price Int Product updateProduct id String name String price Int Product deleteProduct id String deleteResponse type deleteResponse success Boolean message String id String src resolvers products tsimport Product from model products interface Args id string name string price number export const ProductsResolver Query products async gt try const products await Product find if products throw new Error No products found return success true total products length products catch error throw error product async any args Args gt try if args id throw new Error No id provided const product await Product findById args id if product throw new Error No product found return product catch error throw error Mutation addProduct async any args Args gt try const product await Product findOne name args name if product throw new Error Product already exists const newProduct await Product create name args name price args price return newProduct catch error throw error updateProduct async any args Args gt try const id args id if id throw new Error No id provided const product await Product findById args id if product throw new Error No product found const updateProduct await Product findByIdAndUpdate id args new true runValidators true return updateProduct catch error console log error deleteProduct async any args Args gt try const id args id if id throw new Error No id provided const product await Product findById args id if product throw new Error No product found const deleteProduct await Product findByIdAndDelete id return success true message Product deleted successfully id deleteProduct id catch error throw error Similar to the implementation for User entities the schema and resolver for Product entities collaborate seamlessly to offer a comprehensive and structured approach to managing product related operations This cohesive interaction ensures that querying creating updating and deleting products within your GraphQL API are handled efficiently and logically The product schema serves as a blueprint defining the structure of a Product type Just as with the User type this schema outlines the fields that compose a product such as ID name description price and more It specifies not only the fields themselves but also their data types and whether they re required or optional On the other hand the product resolver takes care of the functional aspects In a manner akin to the user resolver it encapsulates the actual logic behind queries and mutations involving products For instance when querying for a list of products the resolver fetches the products from a data source e g a database In our case MongoDB and constructs a well formed response with details about each product Similarly when creating updating or deleting a product the resolver handles the necessary data manipulation validation and interaction with the data source In tandem the schema and resolver form a cohesive unit that makes it straightforward to understand implement and maintain product related operations in your GraphQL API This separation of concerns between defining the structure schema and implementing the functionality resolver contributes to a clean and organized codebase making your API development experience smoother and more structured Now it s time for us to combine all the Schema and resolvers so that we can import a merged type definition and schema into the app ts file Update src schema index tsimport mergeTypeDefs from graphql tools merge import usersGQLSchema from user import productsGQLSchema from products export const mergedGQLSchema mergeTypeDefs usersGQLSchema productsGQLSchema By doing this you re creating a unified GraphQL schema that incorporates all the types and operations defined in the user and product schemas This merged schema can then be imported into your app ts file to create a cohesive GraphQL API that supports both user and product related functionalities Update src resolver index tsimport UsersResolver from user import ProductsResolver from product export const resolvers UsersResolver ProductsResolver When we set up your GraphQL server you ll use this combined array of resolvers along with the merged schema to create a fully functional GraphQL API We re nearing completion and the final step is to construct our app ts file where we ll consolidate the various components we ve developed so far This file will serve as the backbone of our GraphQL application To begin we load environment variables from a env file using the dotenv library ensuring the secure configuration of sensitive data like database connection details and port numbers Importing essential dependencies follows suit These include the function responsible for connecting to the database connectDB as well as the ApolloServer and startStandaloneServer modules that facilitate GraphQL server creation Within this context we define a constant named PORT to encapsulate the port number for our server This value is either extracted from environment variables or defaults to Our ApolloServer instance takes center stage We configure it with the merged GraphQL schema mergedGQLSchema and the combined resolvers resolvers Moreover we enable introspection a valuable tool for introspecting the schema using tools like GraphQL Playground To bring it all to life the start function emerges As an asynchronous function it orchestrates the setup process It employs the connectDB function to establish a connection to the MongoDB database using the URI from environment variables The startStandaloneServer function is then invoked initiating the Apollo server s operation This server listens attentively on the specified port PORT The culmination of this sequence is marked by a console message announcing the server s successful launch With the completion of these steps we culminate the process by invoking the start function This action ignites the journey connecting the database and propelling the GraphQL server into operation This is what our app ts file looks like require dotenv config import connectDB from db connect import ApolloServer from apollo server import startStandaloneServer from apollo server standalone import mergedGQLSchema from schema import resolvers from resolvers const PORT parseInt process env PORT as string const server new ApolloServer typeDefs mergedGQLSchema resolvers resolvers introspection true const start async gt try connectDB process env MONGO URI as string startStandaloneServer server listen port PORT console log Server is listening on port PORT catch error console log error start And with that we re all set To set the server in motion simply execute the command npm run dev or npm start Afterwards pinpoint the endpoint at http localhost If the components fall into place as anticipated your browser will transport you to the interactive Apollo GraphQL Playground This serves as an excellent feature as GraphQL is inherently self documenting The GraphQL Playground an integrated query tool allows you to test and construct queries with ease Much like the functionality found in tools like Postman you can formulate queries explore the schema and gain insights into your API s capabilities firsthand It would look like this Query to get all users Mutation to register a user Mutation to update a productNotice that all endpoints are accessible via http localhost unlike a RESTful design where you would need to define different endpoints for each route This is because of GraphQL s single endpoint architecture and its ability to handle complex data retrieval in a more dynamic manner In a traditional RESTful API design each endpoint typically corresponds to a specific resource or route If you wanted to retrieve different types of data you would need to create distinct endpoints for each resource For example to fetch user information you might have an endpoint like GET users and for products another endpoint like GET products However GraphQL takes a different approach With GraphQL there s a single endpoint that serves as the entry point for all data operations This endpoint is usually accessed via an HTTP POST request Instead of defining multiple endpoints for different resources GraphQL employs a flexible querying system that allows you to request exactly the data you need and nothing more This is where the power of the GraphQL query language shines The client can specify the shape and structure of the data it requires by creating queries that match the types and fields defined in the GraphQL schema It s like asking for a custom made data response tailored to your application s needs Behind the scenes the GraphQL server processes the query and retrieves only the requested data This eliminates the need to create and manage numerous endpoints for different use cases The single endpoint approach simplifies the API structure reduces redundancy and provides a more efficient way to interact with data In essence GraphQL s single endpoint design coupled with its dynamic querying capabilities offers a more streamlined and adaptable approach to handling complex data retrieval compared to the more rigid endpoint structure of traditional RESTful APIs This contributes to the efficiency and flexibility that GraphQL brings to modern API development CONCLUSIONIn conclusion GraphQL presents a host of advantages that make it a compelling choice for modern API development Its flexible querying system empowers clients to precisely request only the data they need eliminating over fetching and under fetching of data commonly associated with RESTful APIs This optimization in data transfer enhances performance reduces unnecessary network traffic and results in faster more efficient interactions Unlike RESTful APIs that often require multiple endpoints for distinct resources GraphQL s single endpoint architecture simplifies API management and reduces the need for versioning With GraphQL you have the freedom to evolve your API without causing disruption to existing clients as fields can be added or deprecated without changing the endpoint structure Furthermore GraphQL s introspection capabilities grant developers access to in depth schema documentation making it a self documenting API This coupled with the integrated query tools like the GraphQL Playground streamlines development debugging and testing However it s essential to acknowledge that GraphQL might not be the optimal solution for every scenario Its flexibility might lead to complex queries potentially putting a heavier load on servers RESTful APIs on the other hand can offer a clearer mapping to underlying data models and cache management due to their predictable nature In comparison GraphQL and RESTful APIs each have their strengths and weaknesses catering to different project requirements While GraphQL excels in scenarios that prioritize flexibility efficient data retrieval and a unified endpoint RESTful APIs can be more suitable for situations where a clear resource oriented structure and caching mechanisms are vital In the journey of building GraphQL APIs we ve traversed the process of creating schemas defining types crafting resolvers and setting up the server The completed code for this tutorial is accessible on Github via GRAPHQL API offering a practical reference for your endeavors To all the readers embarking on this exploration I extend my appreciation for joining this tutorial Whether you choose GraphQL or RESTful APIs may your coding journeys be filled with innovation efficiency and transformative experiences Happy coding | 2023-08-26 16:04:42 |
ニュース | BBC News - Home | England 22-30 Fiji: Pacific island nation beat England for first time | https://www.bbc.co.uk/sport/rugby-union/66629208?at_medium=RSS&at_campaign=KARANGA | England Fiji Pacific island nation beat England for first timeEngland slump to fifth defeat in six matches as Fiji beat them for the first time as both sides end their World Cup preparations at Twickenham | 2023-08-26 16:51:55 |
ニュース | BBC News - Home | Claire Knights: Body found in search for missing dog walker | https://www.bbc.co.uk/news/uk-england-kent-66627075?at_medium=RSS&at_campaign=KARANGA | upstreet | 2023-08-26 16:44:08 |
ニュース | BBC News - Home | Loch Ness Monster: Hundreds join huge search for Nessie | https://www.bbc.co.uk/news/uk-scotland-highlands-islands-66614935?at_medium=RSS&at_campaign=KARANGA | nessie | 2023-08-26 16:41:08 |
ニュース | BBC News - Home | Luis Rubiales: Spain coaching staff resign over Hermoso kiss row | https://www.bbc.co.uk/sport/football/66629505?at_medium=RSS&at_campaign=KARANGA | Luis Rubiales Spain coaching staff resign over Hermoso kiss rowSpain s entire coaching staff from their Women s World Cup win except for head coach Jorge Vilda have resigned over the Luis Rubiales row | 2023-08-26 16:47:48 |
ニュース | BBC News - Home | Manchester United 3-2 Nottingham Forest: Bruno Fernandes' penalty completes turnaround as hosts win from 2-0 down | https://www.bbc.co.uk/sport/football/66552608?at_medium=RSS&at_campaign=KARANGA | Manchester United Nottingham Forest Bruno Fernandes x penalty completes turnaround as hosts win from downBruno Fernandes penalty completes the comeback as Manchester United fight back from down to beat man Nottingham Forest at Old Trafford | 2023-08-26 16:25:25 |
コメント
コメントを投稿