API fetching using RESTDataSource in Apollo server

How fetch API using apollo-datasource-rest in apollo-graphql package


In the last last post on apollo-graphql I guide you to setup Apollo server and in this going to fetch live data from API using Apollo’s in build REST feature.

In this project we are using Todos API, so schema and structure may vary from the first project.

What we need ?

  • A minimal Apollographql project
  • RESTDataSource package
  • Resolvers

RESTDatasource

Install the RESTDataSource from npm and create database/todos-api.js file.

npm install apollo-datasource-rest

Let’s extend a new class from apollo-datasource-rest package and implement our logic.

const {RESTDataSource} = require('apollo-datasource-rest');

class TodoAPI extends RESTDataSource
{
constructor(){
    super();
    this.baseURL='https://jsonplaceholder.typicode.com/';

}
getAllTodos(){
    return this.get("todos");
}
}
module.exports=TodoAPI;  

In this file we simply define baseURL and a getAllTodos method which return the API end point response.

Why I need the REST (apollo), still I have the async fetch ?. Good thought :).

Apollo REST also use the cached data and it is smarter than the async fetch, and fast.

Schema and Resolver

This is our schema and query definitions.

const { gql } = require('apollo-server')

const typeDefs = gql`
type Query{
    "Query to get all todos"
    todos:[Todo!]
    
    }
  
type Todo{
    userId:ID!
    id:Int
    title:String!
    completed:Boolean
}
`;

module.exports = typeDefs;

Resolvers

Resolver function handles the response / data, which should have same name as Query type / schema. We are going to use the REST API within the resolvers

Save the resolvers file in resolvers/todos.js

const resolvers = {
    Query: {
        todos: (_, __, { dataSources }) => {
            return dataSources.todoAPI.getAllTodos();
        },
      
    }
}
module.exports = resolvers;

Resolver Query function should match the type Query (in typeDef) . Every resolver function can have three arguments , namely parent, args, context and info.

Here we skip the first two and the last (Info) ,using _ for skipping first and __ for second.

Our context here is the dataSources and using it we can access the API REST methods.

In the entry point(index.js) we configure the server with following properties

const { ApolloServer } = require('apollo-server');
const typeDefs = require('./schema');
const resolvers = require('./resolvers/todos');
const TodoAPI =require('./datasources/todos-api')

const server = new ApolloServer({ typeDefs,  resolvers,dataSources:()=>{
    return{
        todoAPI:new TodoAPI()
    }
}});


server.listen(4001).then(({ url }) => {
    console.log(`
    Server is running!
    Listening on port ${url}
    Query @ http://studio.apollographql.com/dev
    `);
})

We also need to specify the dataSources as function, along with resolvers.

Let’s run the server and goto the studio.

npm start

[display-posts tag=apollo-server,graphql

Using nuxt.config in Keystone Nuxt-App

How to use Nuxt config in Keystone app


Using the create-key-5-app we can create a boilerplate template for our Nuxt-Keystone app. It automatically configure the folder structure, pacakge.json and src folder where our regular Nuxt app resides.

Also there is a index.js file which is the entry point to the app. We can set up the project manually and then add scripts, dependencies, entry point file, index.js.

Keystone and index.js

@kestonejs/nuxt-app works through the configuration specified in the export. We can use the config object for specify nuxt configurations such as middleware, plugins, env etc.

//as object
....
const config = {
  srcDir: 'src/',
  buildDir: 'dist',
  env:{
    URI:process.env.API
  },
  router:{
    middleware:'Identity'
  },
   buildModules:['@nuxtjs/tailwindcss'],      
  components:true
 
};

module.exports = {
 keystone,
 apps: [new GraphQLApp(), new AdminUIApp(), new NuxtApp(config)],
};

Or we can prepare our nuxt.config as follows and import @ keystone index.js file as follows

//nuxt.config.js
require('dotenv').config()
const config= {
 srcDir: 'src/',
 buildDir: 'dist',
 router: {
   middleware: 'Identity'
},
 
 target: 'static',  
 
 env:{
   URI:proccess.env.API
},
 ....
}
module.exports =config;
//index.js
....
const config= require("./nuxt.config")

module.exports = {
 keystone,
 apps: [new GraphQLApp(), new AdminUIApp(), new NuxtApp(config)],
};

Following Keystone post may help you learn more

How to use graphql queries in Nextjs and Reactjs

How to use graphql end point in React and Nextjs using apollo client


So far we have been explored how to build graphql server functionality for a Nodejs , Nextjs an Nuxtjs projects. If you miss any of the graphql guide, the links are at the end of his post.

How to execute graphql queries ?

For parsing queries and return the result, we need to set up the apollo client. For the project level availability of client require to configure it at _app.js

Install the apollo client using

npm i -s @apollo/client
//_app.js

import {
  ApolloClient,
  InMemoryCache,
  ApolloProvider,
} from "@apollo/client";
​
const client = new ApolloClient({ 
  uri: "http://localhost:3000/api/graphql",
  cache: new InMemoryCache(),
});
​
function MyApp({ Component, pageProps }) {
  return (
    <ApolloProvider client={client} >      
      <Component {...pageProps} />
    </ApolloProvider>
  );
}
​
export default MyApp;
​

Apollo React hook

We can use useQuery hook to execute the query and the will return error,loading and data object. We need not to use the UseStaticProps, in stead invoke hook at Home component as follows.

import { useQuery, gql } from "@apollo/client";
....
const CONTACTS_QUERY = gql`
  {
    contacts {
      id
      name
      email
    }
  }
`;
​
export default function Home() {
  const { loading, error, data } = useQuery(CONTACTS_QUERY);
  let contactList;
  if (data) {    
    contactList = data.contacts.map((c) => (      
       <li key={c.id}>
     {c.name} | {c.email}
     </li>
    ))   
  }
    ....
​

Create API with Prisma + Express + Server Middle Ware in Nuxt

Create a API using serverMiddleware , Prisma and Express in Nuxtjs


Setup Prisma ORM for Nuxtjs project

An API requires special server middleware in nuxt, also we need to create a custom route, express framework will help us manage the route, Prisma ORM, a minimal configurable mapper for managing database.

Prisma is a ORM for JavaScript and Typescript, it let developers easily configure, create / migrate databases using models. One of the cool feature I love mostly is that , it can be configured with few CLI commands like init, migrate

View and Run the code @ sandbox

Setup Prisma

For initializing the Prisma install the developer dependency npm i -d prisma and initialize prisma with

npx prisma init

It will generate necessary files under Prisma folder, please open the file and configure database and models. For demonstration I have configured a Sqlite database, you can use other databases like mysql, postgres, Mongodb etc.

//schema.prisma

datasource db {
 provider = "sqlite"
 url      = "file:./dev.db"
}

generator client {
 provider = "prisma-client-js"
}

model Contact{
 id String @id @default(uuid())
 name String
 email String
}
 

Note the id field in the model, it is a primary key and also auto filled by the uuid() function. One you done models go to generate the real database with migrate command

npx prisam migrate dev --name init

This will generate the tables using the models we defined, to make sure we can use the prisma studio which runs on the port 555, also a standalone studio app is available.

In the future we can modify and rerun the migrate command for updating the tables, which will drop the tables and re-create for us.

// run in new terminal
npmx prisma studio

How to use in our Nuxtjs app

In the nuxtjs app we need the dependency @prisma/client, let’s add them to our project

nmp i -s @prisma/client

In the Nuxt app , we can setup internal API for interacting with database using server middleware.

API routes

In the project folder create a folder api and inside the folder create a file index.ts

For create routes, we can use the express framework the API should export the handler as in Nextjs.

index.ts
import express from "express";
import { PrismaClient, Todo } from "@prisma/client";
const app = express();
const prisma = new PrismaClient();
app.use(express.json());

app.get("/", (req, res) => {
 res.json("Wlcome to API");
});

app.get("/todos", async (req, res) => {
 const todos = await prisma.todo.findMany();
 res.json(todos);
});

export default {
 path: "/api",
 handler: app
};

Nuxt-config

For using Prisma client we need to use PrismaClient object. The API would not work at this point, it also required setup a middleware in the dedicated nuxt-config.

export default {
 // Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
 ssr: false,
 serverMiddleware:[
   '~/api/index.ts',
] ,  
   .....

and now the api can be accessed at http://localhost:3000/api

How to create a Apollo-graphql-server in Nodejs

How to setup a graphql server using Apollo framework and express


Graphql is an alternative approach for the REST API invented by Facebook. It is used for fetch data from a server and put data back to a server , just like the regular API does.

The Graphql shines where you want to fetch few data (required), where REST API fetch a bunch of data, it may cause fetching too much data. API have multiple end points where graphql have one. One of the problem with graphql, it is not simple to create a graphql server, even though once it has been done ,using them is quiet simple.

Play with full code + Graphql Playground in Sandbox

Apollo and Express

With Apollo server we can build and run a graphql server, for creating route for our graphql end point can utilize the node developers favorite express module

Dependencies and Setup

To get started we need to create a folder project and then cd into the folder npm init -y for generating pacakge.json.

We also need to install few Apollo dependencies along with express.

npm i -s apollo-server apollo-core express nodemon

nodemon help us to detect changes and automatically restart server for us.

let’s open the folder in VS Code and create a index.js file ( in root directory ) and also create a script in package.json for running the server as follows

//package.json
"scripts": {
   "test": "echo \"Error: no test specified\" && exit 1",
   "start": "nodemon ./index.js"
},

Mock Data

We also have users list which is used to show some mock data create users.js files with following content in the project root.

//users.js
const users =[
  {
       name:"Dev",
       role: "DBA",
       id:1
  },
  {
       name:"Jhon Doe",
       role: "Admin",
       id:2
  },
  {
       name:"Martin",
       role: "Dev",
       id:3
  }
]
module.exports = users;

How to use GitHub Packages in node project

How to use github package in Node project


Every repo in GH have package link where you find the package. To use a package from GitHub package add the .npmrc file in the root of the project and include the dependency in package.json

.npmrc

This file tell the npm what registries you are using , along side npm registry.

//.npmrc

@OWNER:registry=https://npm.pkg.github.com

Replace the OWNER with organization / user name and add install all the dependencies

npm intsall

following npm posts may help you

​
​

How to publish packages to GitHub Registry

How to publish packages to npm github registry


In GitHub every repository can publish packages, which can be used as dependencies in other projects. There are two type npm registry where we can publish packages,

  • npm registry
  • GitHub npm registry

Which one I should use ? It’s up to you, can try both of them . In this article we are on the GitHub way.

Naming rule

Name of the package should include organization/username and will look like

@organization/name_of_the_pacakage

So adjust name in package.json

Repository

Don’ forget to publish the repository and add it to the package file as follows

"repository":{
 "url": "git://github.com/org_name/some_repo.git"
}

Access Token

We have to use the personal access token to authenticate, we can add the secret to the .npmrc file, so that need not authenticate manually.

Requirements

All thing need to publish a regular npm package also require for Github Package, package.json, readme.md and build project. Additionally requires .npmrc file for registry configuration.

.npmrc

This file can contain the registry information and authentication secrets, we need not expose this file to repository, so that add the file to the .gitignore

//.gitignore

.npmrc
node_modules

In the .npmrc include the registry information along with organization / owner .

@owner:registry=https://npm.pkg.github.com
npm.pkg.github.com/:_authToken=TOKEN

Replace the owner with user/org and TOKEN with personal token generated.

Publish

Let’s jump into terminal issue the npm publish command and it will take few minutes to update. The package will list on the repository as well as on user/org profile page.

Update

How to update package ? Can’t do that ! instead publish new version by change the version in package.json and publish new one.

Remove

For removing, there is dedicated delete button in relevant package.

following npm posts may help you

​
​

How to Update npm package

How to update existing npm packages


We can’t publish a package twice to the npm, registry will check the package’s version. Literally we can’t update existing package, it will remain same.

How do we publish changes?

Since packages need to be updated, we can use different version for new features, it also a good practice that the older version remain same, since there can be apps developed using those versions.

To publish a new version of the existing package, change the version key in the package.json (at the root of the project) and go on publish

npm adduser (optional)
npm publish
or
npm publish --access=public

following npm posts may help you

​
​

How to remove a package from npm registry

How to remove packages from npm registry


May be you won’t see any delete button your npm package list @ npm.js / the package itself, so how do we remove a package from the registry?

The CLI

As we published our package, can also remove entire package or a particular version from the registry too. Issue the following command to login

npm adduser

login to your account using credentials and remove the package using unpublish

npm unpublish <package_name> -f     

make sure to include the scope package name, if it is a private package. -f will force all versions to be removed.

following npm posts may help you

​
​

How to publish a package to NPM registry

How to publish packages to npm registry


NPM is Node based JavaScript package registry. Thousands of packages and libraries are being added to npm daily. To publish a package to npmjs we should have

  • A build project ready to publish
  • Package.json
  • npmjs.com account
  • Readme.md

Name of Package

The name of the package, is the first thing to not in package file. Of course there are millions of already used packages, so the name may not be available, prefer another, make a search on the npmjs. Alternatively we can use scope in name. For example

@mongo/package_name

This will create private package, we can make it public when publishing it. Here the mongo is the npmjs username, and it should be.

Readme.md

Readme help developers to give some usage sample and basic information. If you don’t know the standards, please install VSCode extension for generating README.

Other Package fields

Other fields in standard package files are

{
 "name": "@meo/package_name",
 "version": "1.0.0",
 "description": "Awesome description",
 "author": "Mumi",
 "license": "MIT",
 "keywords": ["color-picker","color","CSS","vuejs","vue-components"],
 "repository": {
 "url": "git://github.com/mue/vue-sfc.git"
  },
   ....
}

Publish

Make sure , build the project properly. Go to terminal (cd into the project) and login to npm using credentials.

npm adduser

Make sure you are login

npm whoami  

If you are using scoped name (@username/pkg) use the following command to make the package available to all

npm publish --access=public

or you can use the

npm publish

and it will be added to your package list on npmjs.

following npm posts may help you

​
​