将查询参数与运算符一起用于集合

时间:2018-02-27 16:50:07

标签: javascript reactjs rest api graphql

在GraphQL中,如何最好地设计一种" API查询语言"使用运算符过滤项目的集合?

例如,在REST中,您可以使用

等参数

/family/people?height="192"&weight[]=">=65"&weight[]="<=100"

在GraphQL中,似乎违反了最佳实践,在GraphQL层之外实现查询逻辑:

{
    family {
        people(height: 192, weight: ['>=65','<=100']) {
            givenName
            surName
            age
        }
    }
}

虽然执行以下操作似乎过于冗长且不太干:

{
    family {
        people(height: 192, weightGte: '65', weightLte: '100') {
            givenName
            surName
            age
        }
    }
}

是否存在具有> < >= <= == != *等运算符的查询参数的约定?

1 个答案:

答案 0 :(得分:1)

我不会说它本身就是一个graphQL问题,而是 - 你选择在你的解决方案上使用的方法。

假设我们正在谈论JS(考虑你的标签),我会用一个函数包装你的查询,类似于:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { catchError, map, tap } from 'rxjs/operators';

import { User } from '../domain/user';
import { MessageService } from '../service/message.service';

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

@Injectable()
export class HomeService {

  private usersUrl: 'http://localhost:8080/users';

  constructor(
    private http: HttpClient,
    private messageService: MessageService
  ) { }

  getUsers (): Observable<User[]> {
    return this.http.get<User[]>(this.usersUrl)
      .pipe(
        tap(users => this.log(`fetched users`)),
        catchError(this.handleError('getUsers', []))
      );
  }

  /**
  * Handle Http operation that failed.
  * Let the app continue.
  * @param operation - name of the operation that failed
  * @param result - optional value to return as the observable result
  */
  private handleError<T> (operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {

      // TODO: send the error to remote logging infrastructure
      console.error(error); // log to console instead

      // TODO: better job of transforming error for user consumption
      this.log(`${operation} failed: ${error.message}`);

      // Let the app keep running by returning an empty result.
      return of(result as T);
    };
  }

  private log(message: string) {
    this.messageService.add(message);
  }

}

根据您的js风格和创建查询文档的方式,您可以使用不同的参数调用它。

如果您重复使用相同的参数,则可以缓存文档并使用缓存版本:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { RouterModule, Routes } from '@angular/router';
import { HttpClientModule } from '@angular/common/http';
import { HttpClientXsrfModule } from '@angular/common/http';

import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { HomeService } from './service/home.service';
import { MessagesComponent } from './messages/messages.component';
import { MessageService } from './service/message.service';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    LoginComponent,
    RegisterComponent,
    MessagesComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    HttpClientXsrfModule.withOptions({
      cookieName: 'My-Xsrf-Cookie',
      headerName: 'My-Xsrf-Header',
    })
  ],
  providers: [HomeService, MessageService],
  bootstrap: [AppComponent]
})
export class AppModule { }